void DoInitializeDependencies(IActivityMonitor m) { var packageRefs = _file.AllFiles.Select(f => f.Document.Root) .SelectMany(root => root.Elements("ItemGroup") .Elements() .Where(e => e.Name.LocalName == "PackageReference" || e.Name.LocalName == "ProjectReference")) .Select(e => (Origin: e, PackageId: (string)e.Attribute("Include"), RawVersion: (string)e.Attribute("Version") ?? (string)e.Element("Version"), PrivateAssets: (string)e.Attribute("PrivateAssets") ?? ( string)e.Element("PrivateAssets") ?? "" )); var conditionEvaluator = new PartialEvaluator(); var deps = new List <DeclaredPackageDependency>(); var uselessDeps = new List <XElement>(); var projs = new List <ProjectToProjectDependency>(); foreach (var p in packageRefs) { if (p.Origin.Name.LocalName == "PackageReference") { if (p.Origin.Attribute("Include") == null) { m.Warn("PackageReference that are not Include are not supported and ignored."); continue; } else { bool isPropVersion; bool versionLocked = false; SVersion version = null; if (string.IsNullOrWhiteSpace(p.PackageId) || string.IsNullOrWhiteSpace(p.RawVersion) || ( !(isPropVersion = p.RawVersion.StartsWith("$(")) && !((versionLocked, version) = SVersionRange.TryParseSimpleRange(m, p.RawVersion)).version.IsValid )) { if (version != null) { m.Error($"Unable to parse Version attribute on element {p.Origin}: {version.ErrorMessage}"); } else { m.Error($"Invalid Include or Version attribute on element {p.Origin}."); } return; } string[] defaultValues = new string[] { "compile", "runtime", "contentFiles", "build", "analyzers", "native" }; XElement propertyDef = null; if (isPropVersion) { propertyDef = FollowRefPropertyVersion(m, p, ref versionLocked, ref version); if (propertyDef == null) { return; } } CKTrait frameworks = ComputeFrameworks(m, p.Origin, conditionEvaluator); if (frameworks == null) { return; } if (frameworks.IsEmpty) { m.Warn($"Useless PackageReference (applies to undeclared frameworks): {p.Origin}."); uselessDeps.Add(p.Origin); continue; } deps.Add(new DeclaredPackageDependency(this, p.PackageId, versionLocked, version, p.Origin, propertyDef, frameworks, p.PrivateAssets)); } } else { //This is a ProjectReference. string projectName = new NormalizedPath(p.PackageId).LastPart; if (!projectName.EndsWith(".csproj")) { m.Error($"ProjectReference must Include a .csproj project: {p.Origin}."); return; } projectName = projectName.Substring(0, projectName.Length - 7); var target = Solution.MSProjects.FirstOrDefault(pRef => pRef.ProjectName == projectName); if (target == null) { m.Warn($"ProjectReference '{p.PackageId}' not found in the solution. Project name '{projectName}' should exist in the solution."); uselessDeps.Add(p.Origin); continue; } CKTrait frameworks = ComputeFrameworks(m, p.Origin, conditionEvaluator); if (frameworks == null) { return; } if (frameworks.IsEmpty) { m.Warn($"Useless ProjectReference (applies to undeclared frameworks): {p.Origin}."); uselessDeps.Add(p.Origin); continue; } projs.Add(new ProjectToProjectDependency(this, target, frameworks, p.Origin)); } } // Consider Solution level dependency as active for all TargetFrameworks. if (!EnumerateSolutionLevelProjectDependencies(m, p => projs.Add(new ProjectToProjectDependency(this, p, TargetFrameworks, null)))) { return; } _dependencies = new Dependencies(deps, projs, uselessDeps); }
void DoInitializeDependencies(IActivityMonitor m) { var packageRefs = _primaryFile.AllFiles.Select(f => f.Document.Root) .SelectMany(root => root.Elements("ItemGroup") .Elements() .Where(e => e.Name.LocalName == "PackageReference" || e.Name.LocalName == "ProjectReference")) .Select(e => (Origin: e, PackageId: (string)e.Attribute("Include"), RawVersion: (string)e.Attribute("Version") ?? (string)e.Element("Version"), PrivateAssets: (string)e.Attribute("PrivateAssets") ?? (string)e.Element("PrivateAssets") ?? "" )); var conditionEvaluator = new PartialEvaluator(); var deps = new List <DeclaredPackageDependency>(); var uselessDeps = new List <XElement>(); var projs = new List <ProjectToProjectDependency>(); foreach (var p in packageRefs) { if (p.Origin.Name.LocalName == "PackageReference") { if (p.Origin.Attribute("Include") == null) { m.Warn($"Element {p.Origin} misses Include attribute. It is ignored."); continue; } else { if (string.IsNullOrWhiteSpace(p.PackageId)) { m.Error($"Invalid Include attribute on element {p.Origin}."); return; } XElement propertyDef = null; bool isVersionOverride = false; bool versionLocked = false; SVersion version = null; if (p.RawVersion == null) { // No Version attribute nor element: we must use Central packages! if (_centralPackagesFile == null) { m.Warn($"Missing Version attribute (or child element) on element {p.Origin} (and Microsoft.Build.CentralPackageVersions is not used). This is ignored."); continue; } else { // We are using CentralPackageVersions: VersionOverride may be used! var vO = (string)p.Origin.Attribute("VersionOverride"); if (vO != null) { isVersionOverride = true; if (!((versionLocked, version) = SVersionRange.TryParseSimpleRange(m, vO)).version.IsValid) { m.Error($"Unable to parse VersionOverride attribute on element {p.Origin}: {version.ErrorMessage}"); return; } m.Warn($"VersionOverride is used for package {p.PackageId}: {vO}."); } } if (!isVersionOverride) { // We must find the <Package Update= ... version. propertyDef = _centralPackagesFile.Document.Root.Elements().Where(e => e.Name.LocalName == "ItemGroup") .Elements().Where(e => e.Name.LocalName == "PackageReference") .FirstOrDefault(e => (string)e.Attribute("Update") == p.PackageId); if (propertyDef == null) { propertyDef = _centralPackagesFile.Document.Root.Elements().Where(e => e.Name.LocalName == "ItemGroup") .Elements().Where(e => e.Name.LocalName == "PackageReference") .FirstOrDefault(e => p.PackageId.Equals((string)e.Attribute("Update"), StringComparison.OrdinalIgnoreCase)); if (propertyDef == null) { m.Error($"Unable to find a version for '{p.PackageId}' in central package file '{_centralPackagesFile.Path}'."); return; } m.Warn($"Found a package version for '{p.PackageId}' in central package file '{_centralPackagesFile.Path}': '{propertyDef.Attribute( "Update" )}' case differ."); } if (!((versionLocked, version) = SVersionRange.TryParseSimpleRange(m, (string)propertyDef.Attribute("Version"))).version.IsValid) { m.Error($"Unable to parse Version attribute on element {propertyDef} in central package file '{_centralPackagesFile.Path}': {version.ErrorMessage}"); } } } else { bool isPropVersion; if (string.IsNullOrWhiteSpace(p.RawVersion) || ( !(isPropVersion = p.RawVersion.StartsWith("$(")) && !((versionLocked, version) = SVersionRange.TryParseSimpleRange(m, p.RawVersion)).version.IsValid )) { if (version != null) { m.Error($"Unable to parse Version attribute on element {p.Origin}: {version.ErrorMessage}"); } else { m.Error($"Invalid Version attribute on element {p.Origin}."); } return; } if (isPropVersion) { propertyDef = FollowRefPropertyVersion(m, p, ref versionLocked, ref version); if (propertyDef == null) { return; } } } string[] defaultValues = new string[] { "compile", "runtime", "contentFiles", "build", "analyzers", "native" }; CKTrait frameworks = ComputeFrameworks(m, p.Origin, conditionEvaluator); if (frameworks == null) { return; } if (frameworks.IsEmpty) { m.Warn($"Useless PackageReference (applies to undeclared frameworks): {p.Origin}."); uselessDeps.Add(p.Origin); continue; } deps.Add(new DeclaredPackageDependency(this, p.PackageId, versionLocked, version, p.Origin, propertyDef, frameworks, p.PrivateAssets, isVersionOverride)); } } else { // This is a ProjectReference. string projectName = new NormalizedPath(p.PackageId).LastPart; if (!projectName.EndsWith(".csproj")) { m.Error($"ProjectReference must Include a .csproj project: {p.Origin}."); return; } projectName = projectName.Substring(0, projectName.Length - 7); var target = Solution.MSProjects.FirstOrDefault(pRef => pRef.ProjectName == projectName); if (target == null) { m.Warn($"ProjectReference '{p.PackageId}' not found in the solution. Project name '{projectName}' should exist in the solution."); uselessDeps.Add(p.Origin); continue; } CKTrait frameworks = ComputeFrameworks(m, p.Origin, conditionEvaluator); if (frameworks == null) { return; } if (frameworks.IsEmpty) { m.Warn($"Useless ProjectReference (applies to undeclared frameworks): {p.Origin}."); uselessDeps.Add(p.Origin); continue; } projs.Add(new ProjectToProjectDependency(this, target, frameworks, p.Origin)); } } // Consider Solution level dependency as active for all TargetFrameworks. if (!EnumerateSolutionLevelProjectDependencies(m, p => projs.Add(new ProjectToProjectDependency(this, p, TargetFrameworks, null)))) { return; } _dependencies = new Dependencies(deps, projs, uselessDeps); }