Example #1
0
        CKTrait ComputeFrameworks(IActivityMonitor m, XElement e, PartialEvaluator evaluator)
        {
            CKTrait frameworks = TargetFrameworks;

            foreach (var framework in TargetFrameworks.AtomicTraits)
            {
                foreach (var(E, C) in e.AncestorsAndSelf()
                         .Select(x => (E: x, C: (string)x.Attribute("Condition")))
                         .Where(x => x.C != null))
                {
                    bool?include = evaluator.EvalFinalResult(m, C, f => f == "$(TargetFramework)" ? framework.ToString() : null);
                    if (include == null)
                    {
                        m.Error($"Unable to evaluate condition of {E}.");
                        return(null);
                    }
                    if (include == false)
                    {
                        frameworks = frameworks.Except(framework);
                    }
                }
            }
            return(frameworks);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }