Example #1
0
        public static PackageIndex Load(IEnumerable <string> packageIndexFiles)
        {
            string indexKey = String.Join("|", packageIndexFiles);

            PackageIndex result = null;

            if (s_indexCache.TryGetValue(indexKey, out result))
            {
                return(result);
            }

            foreach (var packageIndexFile in packageIndexFiles)
            {
                if (result == null)
                {
                    result = Load(packageIndexFile);
                }
                else
                {
                    result.Merge(packageIndexFile);
                }
            }

            s_indexCache[indexKey] = result;

            return(result);
        }
Example #2
0
        private void UpdateFromValues(PackageIndex index, string id, NuGetVersion version, IEnumerable <Version> assemblyVersions)
        {
            PackageInfo info = GetOrCreatePackageInfo(index, id);

            var packageVersion = VersionUtility.As3PartVersion(version.Version);

            // if we have a stable version, add it to the stable versions list
            if (!version.IsPrerelease)
            {
                info.StableVersions.Add(packageVersion);
            }

            if (assemblyVersions != null)
            {
                var assmVersions = new HashSet <Version>(assemblyVersions.Where(v => v != null));

                foreach (var assemblyVersion in assmVersions)
                {
                    info.AddAssemblyVersionInPackage(assemblyVersion, packageVersion);
                }

                // remove any assembly mappings which claim to be in this package version, but aren't in the assemblyList
                var orphanedAssemblyVersions = info.AssemblyVersionInPackageVersion
                                               .Where(pair => pair.Value == packageVersion && !assmVersions.Contains(pair.Key))
                                               .Select(pair => pair.Key)
                                               .ToArray();

                foreach (var orphanedAssemblyVersion in orphanedAssemblyVersions)
                {
                    info.AssemblyVersionInPackageVersion.Remove(orphanedAssemblyVersion);
                }
            }
        }
Example #3
0
        public static PackageIndex Load(IEnumerable <string> packageIndexFiles)
        {
            string indexKey = String.Join("|",
                                          packageIndexFiles.Select(packageIndexFile => new FileInfo(packageIndexFile))
                                          .Select(packageIndexFileInfo => $"{packageIndexFileInfo.FullName}:{packageIndexFileInfo.Length}:{packageIndexFileInfo.LastWriteTimeUtc.Ticks}"));

            PackageIndex result = null;

            if (s_indexCache.TryGetValue(indexKey, out result))
            {
                return(result);
            }

            foreach (var packageIndexFile in packageIndexFiles)
            {
                if (result == null)
                {
                    result = Load(packageIndexFile);
                }
                else
                {
                    result.Merge(packageIndexFile);
                }
            }

            s_indexCache[indexKey] = result;

            return(result);
        }
Example #4
0
        private void UpdateFromFolderLayout(PackageIndex index, string path, bool filter = false)
        {
            var version = NuGetVersion.Parse(Path.GetFileName(path));
            var id      = Path.GetFileName(Path.GetDirectoryName(path));

            if (filter && !ShouldInclude(id))
            {
                return;
            }

            string refFolder = Path.Combine(path, "ref");

            if (!Directory.Exists(refFolder))
            {
                refFolder = Path.Combine(path, "lib");
            }

            IEnumerable <Version> assemblyVersions = null;

            if (Directory.Exists(refFolder))
            {
                assemblyVersions = Directory.EnumerateFiles(refFolder, "*.dll", SearchOption.AllDirectories)
                                   .Select(f => VersionUtility.GetAssemblyVersion(f));
            }

            UpdateFromValues(index, id, version, assemblyVersions);
        }
        public void GetLastStablePackagesFromIndex()
        {
            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            List <ITaskItem> lastStablePackages = new List <ITaskItem>();

            foreach (var latestPackage in LatestPackages)
            {
                var packageId = latestPackage.ItemSpec;

                var          versionString = latestPackage.GetMetadata("Version");
                NuGetVersion nuGetVersion  = null;
                if (versionString == null || !NuGetVersion.TryParse(versionString, out nuGetVersion))
                {
                    Log.LogMessage($"Could not parse version {versionString} for LatestPackage {packageId}, will use latest stable.");
                }

                var latestVersion = nuGetVersion?.Version;

                PackageInfo info;
                if (index.Packages.TryGetValue(packageId, out info))
                {
                    var candidateVersions = (latestVersion == null) ? info.StableVersions : info.StableVersions.Where(sv => VersionUtility.As4PartVersion(sv) < latestVersion);

                    if (candidateVersions.Any())
                    {
                        lastStablePackages.Add(CreateItem(latestPackage, candidateVersions.Max()));
                    }
                }
            }

            LastStablePackages = lastStablePackages.ToArray();
        }
Example #6
0
        /// <summary>
        /// Merges another packageIndex into this package index.  For any overlapping
        /// data 'other' has precedence.
        /// </summary>
        /// <param name="other"></param>
        public void Merge(PackageIndex other)
        {
            if (other.IndexSources.IsSubsetOf(IndexSources))
            {
                return;
            }

            foreach (var otherPackage in other.Packages)
            {
                var         otherInfo = otherPackage.Value;
                PackageInfo existingInfo;

                if (Packages.TryGetValue(otherPackage.Key, out existingInfo))
                {
                    existingInfo.Merge(otherInfo);
                }
                else
                {
                    Packages[otherPackage.Key] = otherInfo;
                }
            }

            foreach (var otherModuleToPackage in other.ModulesToPackages)
            {
                ModulesToPackages[otherModuleToPackage.Key] = otherModuleToPackage.Value;
            }

            foreach (var otherIndexSource in other.IndexSources)
            {
                IndexSources.Add(otherIndexSource);
            }
        }
Example #7
0
        public override bool Execute()
        {
            if (References == null || References.Length == 0)
            {
                return(true);
            }

            if (PackageIndexes == null && PackageIndexes.Length == 0)
            {
                Log.LogError("PackageIndexes argument must be specified");
                return(false);
            }

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            Dictionary <string, ITaskItem> packageReferences  = new Dictionary <string, ITaskItem>();
            Dictionary <string, ITaskItem> assemblyReferences = new Dictionary <string, ITaskItem>();

            bool referencesMscorlib = false;

            NuGetFramework targetFx = NuGetFramework.Parse(TargetFramework);

            foreach (var reference in References)
            {
                string referenceName = reference.ItemSpec;
                referencesMscorlib |= referenceName.Equals("mscorlib");
                string referenceVersion = reference.GetMetadata("Version");
                reference.SetMetadata("TargetFramework", TargetFramework);
                if (!string.IsNullOrEmpty(TargetFramework) && index.IsInbox(referenceName, targetFx, referenceVersion))
                {
                    AddReference(assemblyReferences, reference);
                }
                else
                {
                    AddReference(packageReferences, reference);
                }
            }

            if (referencesMscorlib)
            {
                // only add framework references for mscorlib-based assemblies.
                FrameworkReferences = assemblyReferences.Values.ToArray();
            }

            if (packageReferences.Count == 0)
            {
                var emptyItem = new TaskItem("_._");
                emptyItem.SetMetadata("TargetFramework", TargetFramework);
                packageReferences.Add(emptyItem.ItemSpec, emptyItem);
            }

            PackageReferences = packageReferences.Values.ToArray();


            return(true);
        }
Example #8
0
        public override bool Execute()
        {
            if (PackageIndexes == null && PackageIndexes.Length == 0)
            {
                Log.LogError("PackageIndexes argument must be specified");
                return(false);
            }

            index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            List <ITaskItem> promotedDependencies = new List <ITaskItem>();

            var dependencies = Dependencies.Select(d => new Dependency(d)).ToArray();

            var refSets = dependencies.Where(d => d.Id != "_._").Where(d => d.IsReference).GroupBy(d => NuGetFramework.Parse(d.TargetFramework)).ToDictionary(g => g.Key, g => g.ToArray());
            var refFxs  = refSets.Keys.ToArray();

            Log.LogMessage(LogImportance.Low, $"Ref frameworks {string.Join(";", refFxs.Select(f => f.ToString()))}");

            var libSets = dependencies.Where(d => !d.IsReference).GroupBy(d => NuGetFramework.Parse(d.TargetFramework)).ToDictionary(g => g.Key, g => g.ToArray());
            var libFxs  = libSets.Keys.ToArray();

            Log.LogMessage(LogImportance.Low, $"Lib frameworks {string.Join(";", libFxs.Select(f => f.ToString()))}");

            if (libFxs.Length > 0)
            {
                foreach (var refFx in refFxs)
                {
                    // find best lib (if any)
                    var nearestLibFx = FrameworkUtilities.GetNearest(refFx, libFxs);

                    if (nearestLibFx != null && !nearestLibFx.Equals(refFx))
                    {
                        promotedDependencies.AddRange(CopyDependencies(libSets[nearestLibFx], refFx));
                    }
                }
            }

            if (refFxs.Length > 0)
            {
                foreach (var libFx in libFxs)
                {
                    // find best lib (if any)
                    var nearestRefFx = FrameworkUtilities.GetNearest(libFx, refFxs);

                    if (nearestRefFx != null && !nearestRefFx.Equals(libFx))
                    {
                        promotedDependencies.AddRange(CopyDependencies(refSets[nearestRefFx], libFx));
                    }
                }
            }

            PromotedDependencies = promotedDependencies.ToArray();

            return(!Log.HasLoggedErrors);
        }
        public override bool Execute()
        {
            if (null == OriginalPackages || OriginalPackages.Length == 0)
            {
                Log.LogError($"{nameof(OriginalPackages)} argument must be specified");
                return(false);
            }

            if (String.IsNullOrEmpty(PreReleaseSuffix))
            {
                Log.LogError($"{nameof(PreReleaseSuffix)} argument must be specified");
                return(false);
            }

            if (PackageIndexes != null && PackageIndexes.Length > 0)
            {
                _index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
            }
            else
            {
                LoadStablePackages();
            }

            List <ITaskItem> updatedPackages = new List <ITaskItem>();

            foreach (var originalPackage in OriginalPackages)
            {
                string packageId = originalPackage.ItemSpec;

                if (packageId == "_._")
                {
                    updatedPackages.Add(originalPackage);
                    continue;
                }

                TaskItem updatedPackage = new TaskItem(originalPackage);
                Version  packageVersion = ParseAs3PartVersion(originalPackage.GetMetadata("Version"));

                if (!IsStable(packageId, packageVersion))
                {
                    // pre-release, set with suffix
                    updatedPackage.SetMetadata("Version", packageVersion.ToString() + GetSuffix(packageId));
                }
                else
                {
                    // stable, just set the 3 part version without suffix
                    updatedPackage.SetMetadata("Version", packageVersion.ToString());
                }

                updatedPackages.Add(updatedPackage);
            }

            UpdatedPackages = updatedPackages.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #10
0
        /// <summary>
        /// Merges another packageIndex into this package index.  For any overlapping
        /// data 'other' has precedence.
        /// </summary>
        /// <param name="other"></param>
        public void Merge(PackageIndex other)
        {
            if (other.IndexSources.IsSubsetOf(IndexSources))
            {
                return;
            }

            // if pre-release is set on this index and different than the other
            // move pre-release to individual infos
            if (PreRelease != null && !PreRelease.Equals(other.PreRelease))
            {
                foreach (var info in Packages.Values)
                {
                    if (info.PreRelease == null)
                    {
                        info.PreRelease = PreRelease;
                    }
                }

                PreRelease = null;
            }

            foreach (var otherPackage in other.Packages)
            {
                var         otherInfo = otherPackage.Value;
                PackageInfo info;

                if (Packages.TryGetValue(otherPackage.Key, out info))
                {
                    info.Merge(otherInfo);
                }
                else
                {
                    Packages[otherPackage.Key] = info = otherInfo;

                    // if pre-release is set on the other index and doesn't match the value of the info, set it
                    if (other.PreRelease != null && !other.PreRelease.Equals(info.PreRelease))
                    {
                        info.PreRelease = other.PreRelease;
                    }
                }
            }

            foreach (var otherModuleToPackage in other.ModulesToPackages)
            {
                ModulesToPackages[otherModuleToPackage.Key] = otherModuleToPackage.Value;
            }

            MetaPackages.Merge(other.MetaPackages);

            foreach (var otherIndexSource in other.IndexSources)
            {
                IndexSources.Add(otherIndexSource);
            }
        }
Example #11
0
        public override bool Execute()
        {
            if (!Apply)
            {
                UpdatedDependencies = OriginalDependencies;
                return(true);
            }

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
            List <ITaskItem> updatedDependencies = new List <ITaskItem>();

            var suppressMetaPackages = new HashSet <string>(SuppressMetaPackages.NullAsEmpty(), StringComparer.OrdinalIgnoreCase);

            // We cannot add a dependency to a meta-package from a package that itself is part of the meta-package otherwise we create a cycle
            var metaPackageThisPackageIsIn = index.MetaPackages.GetMetaPackageId(PackageId);

            if (metaPackageThisPackageIsIn != null)
            {
                suppressMetaPackages.Add(metaPackageThisPackageIsIn);
            }

            // keep track of meta-package dependencies to add by framework so that we only add them once per framework.
            Dictionary <string, HashSet <NuGetFramework> > metaPackagesToAdd = new Dictionary <string, HashSet <NuGetFramework> >();

            foreach (var originalDependency in OriginalDependencies)
            {
                var metaPackage = index.MetaPackages.GetMetaPackageId(originalDependency.ItemSpec);

                if (metaPackage != null && !suppressMetaPackages.Contains(metaPackage))
                {
                    // convert to meta-package dependency
                    var tfm = originalDependency.GetMetadata("TargetFramework");
                    var fx  = NuGetFramework.Parse(tfm);

                    HashSet <NuGetFramework> metaPackageFrameworks;

                    if (!metaPackagesToAdd.TryGetValue(metaPackage, out metaPackageFrameworks))
                    {
                        metaPackagesToAdd[metaPackage] = metaPackageFrameworks = new HashSet <NuGetFramework>();
                    }

                    metaPackageFrameworks.Add(fx);
                }
                else
                {
                    updatedDependencies.Add(originalDependency);
                }
            }

            updatedDependencies.AddRange(metaPackagesToAdd.SelectMany(pair => pair.Value.Select(tfm => CreateDependency(pair.Key, tfm))));

            UpdatedDependencies = updatedDependencies.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #12
0
        private PackageInfo GetOrCreatePackageInfo(PackageIndex index, string id)
        {
            PackageInfo info;

            if (!index.Packages.TryGetValue(id, out info))
            {
                index.Packages[id] = info = new PackageInfo();
            }

            return(info);
        }
Example #13
0
        private void UpdateFromFolderLayout(PackageIndex index, string path, bool filter = false)
        {
            var version = NuGetVersion.Parse(Path.GetFileName(path));
            var id      = Path.GetFileName(Path.GetDirectoryName(path));

            if (filter && !ShouldInclude(id))
            {
                return;
            }

            var dlls = Directory.EnumerateFiles(path, "*.dll", SearchOption.AllDirectories);

            var assemblyVersions = dlls.Select(f => VersionUtility.GetAssemblyVersion(f));
            var dllNames         = dlls.Select(f => Path.GetFileNameWithoutExtension(f)).Distinct();

            UpdateFromValues(index, id, version, assemblyVersions, dllNames);
        }
Example #14
0
        private void UpdateFromValues(PackageIndex index, string id, NuGetVersion version, IEnumerable <Version> assemblyVersions)
        {
            PackageInfo info = GetOrCreatePackageInfo(index, id);

            var packageVersion = VersionUtility.As3PartVersion(version.Version);

            // if we have a stable version, add it to the stable versions list
            if (!version.IsPrerelease)
            {
                info.StableVersions.Add(packageVersion);
            }

            if (assemblyVersions != null)
            {
                foreach (var assemblyVersion in assemblyVersions.Where(v => v != null))
                {
                    info.AddAssemblyVersionInPackage(assemblyVersion, packageVersion);
                }
            }
        }
Example #15
0
        public override bool Execute()
        {
            IDictionary <string, string> modulesToPackages;

            if (PackageIndexes != null && PackageIndexes.Length > 0)
            {
                var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

                modulesToPackages = index.ModulesToPackages;
            }
            else
            {
                modulesToPackages = new Dictionary <string, string>();

                foreach (var modulePackage in ModulePackages.NullAsEmpty())
                {
                    modulesToPackages.Add(modulePackage.ItemSpec, modulePackage.GetMetadata("Package"));
                }
            }

            List <ITaskItem> packagesReferenced = new List <ITaskItem>();

            foreach (var moduleReferenced in ModulesReferenced)
            {
                string moduleName = moduleReferenced.ItemSpec;
                string packageId;

                if (modulesToPackages.TryGetValue(moduleName, out packageId))
                {
                    var packageReferenced = new TaskItem(packageId);
                    packageReferenced.SetMetadata("NativeLibrary", moduleName);
                    moduleReferenced.CopyMetadataTo(packageReferenced);
                    packagesReferenced.Add(packageReferenced);
                }
            }

            PackagesReferenced = packagesReferenced.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #16
0
        public override bool Execute()
        {
            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
            List <ITaskItem> updatedDependencies = new List <ITaskItem>();

            // keep track of meta-package dependencies to add by framework so that we only add them once per framework.
            Dictionary <string, HashSet <NuGetFramework> > metaPackagesToAdd = new Dictionary <string, HashSet <NuGetFramework> >();

            foreach (var originalDependency in OriginalDependencies)
            {
                var metaPackage = index.MetaPackages.GetMetaPackageId(originalDependency.ItemSpec);

                if (metaPackage != null)
                {
                    // convert to meta-package dependency
                    var tfm = originalDependency.GetMetadata("TargetFramework");
                    var fx  = NuGetFramework.Parse(tfm);

                    HashSet <NuGetFramework> metaPackageFrameworks;

                    if (!metaPackagesToAdd.TryGetValue(metaPackage, out metaPackageFrameworks))
                    {
                        metaPackagesToAdd[metaPackage] = metaPackageFrameworks = new HashSet <NuGetFramework>();
                    }

                    metaPackageFrameworks.Add(fx);
                }
                else
                {
                    updatedDependencies.Add(originalDependency);
                }
            }

            updatedDependencies.AddRange(metaPackagesToAdd.SelectMany(pair => pair.Value.Select(tfm => CreateDependency(pair.Key, tfm))));

            UpdatedDependencies = updatedDependencies.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #17
0
        public override bool Execute()
        {
            if (PackageIndexes == null && PackageIndexes.Length == 0)
            {
                Log.LogError("PackageIndexes argument must be specified");
                return(false);
            }

            if (String.IsNullOrEmpty(AssemblyName))
            {
                Log.LogError("AssemblyName argument must be specified");
                return(false);
            }

            Log.LogMessage(LogImportance.Low, "Determining inbox frameworks for {0}, {1}", AssemblyName, AssemblyVersion);

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            InboxFrameworks = index.GetInboxFrameworks(AssemblyName, AssemblyVersion).Select(fx => fx.GetShortFolderName()).ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #18
0
        private void UpdateFromPackage(PackageIndex index, string packagePath, bool filter = false)
        {
            string                id;
            NuGetVersion          version;
            IEnumerable <Version> assemblyVersions;

            using (var reader = new PackageArchiveReader(packagePath))
            {
                var identity = reader.GetIdentity();
                id      = identity.Id;
                version = identity.Version;

                if (filter && !ShouldInclude(id))
                {
                    return;
                }

                var refFiles = reader.GetFiles("ref").Where(r => !NuGetAssetResolver.IsPlaceholder(r));

                if (!refFiles.Any())
                {
                    refFiles = reader.GetFiles("lib");
                }

                assemblyVersions = refFiles.Select(refFile =>
                {
                    using (var refStream = reader.GetStream(refFile))
                        using (var memStream = new MemoryStream())
                        {
                            refStream.CopyTo(memStream);
                            memStream.Seek(0, SeekOrigin.Begin);
                            return(VersionUtility.GetAssemblyVersion(memStream));
                        }
                }).ToArray();
            }

            UpdateFromValues(index, id, version, assemblyVersions);
        }
        public override bool Execute()
        {
            Func <string, bool> isKnownPackage;

            if (PackageIndexes != null && PackageIndexes.Length > 0)
            {
                var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
                isKnownPackage = packageId => index.Packages.ContainsKey(packageId);
            }
            else
            {
                var baseLinePackageIds = new HashSet <string>(BaseLinePackages.NullAsEmpty().Select(b => b.ItemSpec));
                isKnownPackage = packageId => baseLinePackageIds.Contains(packageId);
            }

            FilteredDependencies = OriginalDependencies.Where(
                dependency =>
                !dependency.ItemSpec.StartsWith("System.Private") ||      // only apply filtering to System.Private dependencies
                isKnownPackage(dependency.ItemSpec)
                ).ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #20
0
        private void UpdateFromPackage(PackageIndex index, string packagePath, bool filter = false)
        {
            string                id;
            NuGetVersion          version;
            IEnumerable <Version> assemblyVersions;
            IEnumerable <string>  dllNames;

            using (var reader = new PackageArchiveReader(packagePath))
            {
                var identity = reader.GetIdentity();
                id      = identity.Id;
                version = identity.Version;

                if (filter && !ShouldInclude(id))
                {
                    return;
                }

                var dlls = reader.GetFiles().Where(f => Path.GetExtension(f).Equals(".dll", StringComparison.OrdinalIgnoreCase));

                assemblyVersions = dlls.Select(refFile =>
                {
                    using (var refStream = reader.GetStream(refFile))
                        using (var memStream = new MemoryStream())
                        {
                            refStream.CopyTo(memStream);
                            memStream.Seek(0, SeekOrigin.Begin);
                            return(VersionUtility.GetAssemblyVersion(memStream));
                        }
                }).ToArray();

                dllNames = dlls.Select(f => Path.GetFileNameWithoutExtension(f)).Distinct().ToArray();
            }

            UpdateFromValues(index, id, version, assemblyVersions, dllNames);
        }
Example #21
0
        public void GetBaseLinedDependenciesFromIndex()
        {
            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            List <ITaskItem> baseLinedDependencies = new List <ITaskItem>();

            foreach (var dependency in OriginalDependencies)
            {
                Version assemblyVersion = null, packageVersion = null, baseLineVersion = null;
                string  packageId = dependency.ItemSpec;
                Version.TryParse(dependency.GetMetadata("Version"), out packageVersion);
                Version.TryParse(dependency.GetMetadata("AssemblyVersion"), out assemblyVersion);

                // if we have an assembly version see if we have a better package version
                if (assemblyVersion != null)
                {
                    packageVersion = index.GetPackageVersionForAssemblyVersion(packageId, assemblyVersion);
                }

                if (Apply &&
                    index.TryGetBaseLineVersion(packageId, out baseLineVersion) &&
                    (packageVersion == null || baseLineVersion > packageVersion))
                {
                    packageVersion = baseLineVersion;
                }

                if (packageVersion != assemblyVersion)
                {
                    dependency.SetMetadata("Version", packageVersion.ToString());
                }

                baseLinedDependencies.Add(dependency);
            }

            BaseLinedDependencies = baseLinedDependencies.ToArray();
        }
Example #22
0
        public override bool Execute()
        {
            if (!Apply)
            {
                UpdatedDependencies = OriginalDependencies;
                return(true);
            }

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
            List <ITaskItem> updatedDependencies = new List <ITaskItem>();

            var suppressMetaPackages = new Dictionary <string, HashSet <string> >();

            if (SuppressMetaPackages != null)
            {
                foreach (ITaskItem metapackage in SuppressMetaPackages)
                {
                    if (!suppressMetaPackages.TryGetValue(metapackage.ItemSpec, out var value))
                    {
                        value = new HashSet <string>();
                        suppressMetaPackages.Add(metapackage.ItemSpec, value);
                    }
                    var tfmSpecificSupression = metapackage.GetMetadata("TargetFramework");
                    if (string.IsNullOrEmpty(tfmSpecificSupression))
                    {
                        // If the supression doesn't specify a TargetFramework, then it applies to all.
                        value.Add("All");
                    }
                    else
                    {
                        var fx = NuGetFramework.Parse(tfmSpecificSupression);
                        value.Add(fx.DotNetFrameworkName);
                    }
                }
            }

            // We cannot add a dependency to a meta-package from a package that itself is part of the meta-package otherwise we create a cycle
            var metaPackageThisPackageIsIn = index.MetaPackages.GetMetaPackageId(PackageId);

            if (metaPackageThisPackageIsIn != null)
            {
                suppressMetaPackages.Add(metaPackageThisPackageIsIn, new HashSet <string> {
                    "All"
                });
            }

            // keep track of meta-package dependencies to add by framework so that we only add them once per framework.
            Dictionary <string, HashSet <NuGetFramework> > metaPackagesToAdd = new Dictionary <string, HashSet <NuGetFramework> >();

            foreach (var originalDependency in OriginalDependencies)
            {
                var metaPackage = index.MetaPackages.GetMetaPackageId(originalDependency.ItemSpec);

                // convert to meta-package dependency
                var tfm = originalDependency.GetMetadata("TargetFramework");
                var fx  = NuGetFramework.Parse(tfm);

                if (metaPackage != null && !ShouldSuppressMetapackage(suppressMetaPackages, metaPackage, fx))
                {
                    HashSet <NuGetFramework> metaPackageFrameworks;

                    if (!metaPackagesToAdd.TryGetValue(metaPackage, out metaPackageFrameworks))
                    {
                        metaPackagesToAdd[metaPackage] = metaPackageFrameworks = new HashSet <NuGetFramework>();
                    }

                    metaPackageFrameworks.Add(fx);
                }
                else
                {
                    updatedDependencies.Add(originalDependency);
                }
            }

            updatedDependencies.AddRange(metaPackagesToAdd.SelectMany(pair => pair.Value.Select(tfm => CreateDependency(pair.Key, tfm))));

            UpdatedDependencies = updatedDependencies.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #23
0
        /* Given a set of available frameworks ("InboxOnTargetFrameworks"), and a list of desired frameworks,
         * reduce the set of frameworks to the minimum set of frameworks which is compatible (preferring inbox frameworks. */
        public override bool Execute()
        {
            if (null == Dependencies)
            {
                Log.LogError("Dependencies argument must be specified");
                return(false);
            }
            if (PackageIndexes == null && PackageIndexes.Length == 0)
            {
                Log.LogError("PackageIndexes argument must be specified");
                return(false);
            }

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            // Retrieve the list of dependency group TFM's
            var dependencyGroups = Dependencies
                                   .Select(dependencyItem => new TaskItemPackageDependency(dependencyItem))
                                   .GroupBy(dependency => dependency.TargetFramework)
                                   .Select(dependencyGrouping => new TaskItemPackageDependencyGroup(dependencyGrouping.Key, dependencyGrouping))
                                   .ToArray();

            // Prepare a resolver for evaluating if candidate frameworks are actually supported by the package
            PackageItem[]      packageItems = Files.Select(f => new PackageItem(f)).ToArray();
            var                packagePaths = packageItems.Select(pi => pi.TargetPath);
            NuGetAssetResolver resolver     = new NuGetAssetResolver(null, packagePaths);

            // Determine all inbox frameworks which are supported by this package
            var supportedInboxFrameworks = index.GetAlllInboxFrameworks().Where(fx => IsSupported(fx, resolver));

            var newDependencyGroups = new Queue <TaskItemPackageDependencyGroup>();

            // For each inbox framework determine its best compatible dependency group and create an explicit group, trimming out any inbox dependencies
            foreach (var supportedInboxFramework in supportedInboxFrameworks)
            {
                var nearestDependencyGroup = dependencyGroups.GetNearest(supportedInboxFramework);

                // We found a compatible dependency group that is not the same as this framework
                if (nearestDependencyGroup != null && nearestDependencyGroup.TargetFramework != supportedInboxFramework)
                {
                    // remove all dependencies which are inbox on supportedInboxFramework
                    var filteredDependencies = nearestDependencyGroup.Packages.Where(d => !index.IsInbox(d.Id, supportedInboxFramework, d.AssemblyVersion)).ToArray();

                    newDependencyGroups.Enqueue(new TaskItemPackageDependencyGroup(supportedInboxFramework, filteredDependencies));
                }
            }

            // Remove any redundant groups from the added set (EG: net45 and net46 with the same set of dependencies)
            int groupsToCheck = newDependencyGroups.Count;

            for (int i = 0; i < groupsToCheck; i++)
            {
                // to determine if this is a redundant group, we dequeue so that it won't be considered in the following check for nearest group.
                var group = newDependencyGroups.Dequeue();

                // of the remaining groups, find the most compatible one
                var nearestGroup = newDependencyGroups.Concat(dependencyGroups).GetNearest(group.TargetFramework);

                // either we found no compatible group,
                // or the closest compatible group has different dependencies,
                // or the closest compatible group is portable and this is not (Portable profiles have different framework precedence, https://github.com/NuGet/Home/issues/6483),
                // keep it in the set of additions
                if (nearestGroup == null ||
                    !group.Packages.SetEquals(nearestGroup.Packages) ||
                    FrameworkUtilities.IsPortableMoniker(group.TargetFramework) != FrameworkUtilities.IsPortableMoniker(nearestGroup.TargetFramework))
                {
                    // not redundant, keep it in the queue
                    newDependencyGroups.Enqueue(group);
                }
            }

            // Build the items representing added dependency groups.
            List <ITaskItem> trimmedDependencies = new List <ITaskItem>();

            foreach (var newDependencyGroup in newDependencyGroups)
            {
                if (newDependencyGroup.Packages.Count == 0)
                {
                    // no dependencies (all inbox), use a placeholder dependency.
                    var item = new TaskItem(PlaceHolderDependency);
                    item.SetMetadata("TargetFramework", newDependencyGroup.TargetFramework.GetShortFolderName());
                    trimmedDependencies.Add(item);
                }
                else
                {
                    foreach (var dependency in newDependencyGroup.Packages)
                    {
                        var item = new TaskItem(dependency.Item);
                        // emit CopiedFromTargetFramework to aide in debugging.
                        item.SetMetadata("CopiedFromTargetFramework", item.GetMetadata("TargetFramework"));
                        item.SetMetadata("TargetFramework", newDependencyGroup.TargetFramework.GetShortFolderName());
                        trimmedDependencies.Add(item);
                    }
                }
            }
            TrimmedDependencies = trimmedDependencies.ToArray();
            return(!Log.HasLoggedErrors);
        }
Example #24
0
        private void LoadSupport()
        {
            _frameworks = new Dictionary <NuGetFramework, ValidationFramework>();

            // determine which TxM:RIDs should be considered for support based on Frameworks item
            foreach (var framework in Frameworks)
            {
                NuGetFramework fx;
                try
                {
                    fx = FrameworkUtilities.ParseNormalized(framework.ItemSpec);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse Framework {framework.ItemSpec}. {ex}");
                    continue;
                }

                if (fx.Equals(NuGetFramework.UnsupportedFramework))
                {
                    Log.LogError($"Did not recognize {framework.ItemSpec} as valid Framework.");
                    continue;
                }

                string runtimeIdList = framework.GetMetadata("RuntimeIDs");

                if (_frameworks.ContainsKey(fx))
                {
                    Log.LogError($"Framework {fx} has been listed in Frameworks more than once.");
                    continue;
                }

                _frameworks[fx] = new ValidationFramework(fx);

                if (!String.IsNullOrWhiteSpace(runtimeIdList))
                {
                    _frameworks[fx].RuntimeIds = runtimeIdList.Split(';');
                }
            }

            // keep a list of explicitly listed supported frameworks so that we can check for conflicts.
            HashSet <NuGetFramework> explicitlySupportedFrameworks = new HashSet <NuGetFramework>(NuGetFramework.Comparer);

            // determine what version should be supported based on SupportedFramework items
            foreach (var supportedFramework in SupportedFrameworks)
            {
                NuGetFramework fx;
                string         fxString           = supportedFramework.ItemSpec;
                bool           isExclusiveVersion = fxString.Length > 1 && fxString[0] == '[' && fxString[fxString.Length - 1] == ']';
                if (isExclusiveVersion)
                {
                    fxString = fxString.Substring(1, fxString.Length - 2);
                }

                try
                {
                    fx = FrameworkUtilities.ParseNormalized(fxString);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse TargetFramework {fxString} as a SupportedFramework. {ex}");
                    continue;
                }

                if (fx.Equals(NuGetFramework.UnsupportedFramework))
                {
                    Log.LogError($"Did not recognize TargetFramework {fxString} as a SupportedFramework.");
                    continue;
                }

                Version supportedVersion;
                string  version = supportedFramework.GetMetadata("Version");
                try
                {
                    supportedVersion = Version.Parse(version);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse Version {version} on SupportedFramework item {supportedFramework.ItemSpec}. {ex}");
                    continue;
                }

                ValidationFramework validationFramework = null;
                if (!_frameworks.TryGetValue(fx, out validationFramework))
                {
                    Log.LogError($"SupportedFramework {fx} was specified but is not part of the Framework list to use for validation.");
                    continue;
                }


                if (explicitlySupportedFrameworks.Contains(fx))
                {
                    if (supportedVersion <= validationFramework.SupportedVersion)
                    {
                        // if we've already picked up a higher/equal version, prefer it
                        continue;
                    }
                }
                else
                {
                    explicitlySupportedFrameworks.Add(fx);
                }

                validationFramework.SupportedVersion = supportedVersion;

                if (!isExclusiveVersion)
                {
                    // find all frameworks of higher version, sorted by version ascending
                    IEnumerable <ValidationFramework> higherFrameworks = _frameworks.Values.Where(vf => vf.Framework.Framework == fx.Framework && vf.Framework.Version > fx.Version).OrderBy(vf => vf.Framework.Version);

                    // netcore50 is the last `netcore` framework, after that we use `uap`
                    if (fx.Framework == FrameworkConstants.FrameworkIdentifiers.NetCore)
                    {
                        var uapFrameworks = _frameworks.Values.Where(vf => vf.Framework.Framework == FrameworkConstants.FrameworkIdentifiers.UAP).OrderBy(vf => vf.Framework.Version);
                        higherFrameworks = higherFrameworks.Concat(uapFrameworks);
                    }


                    foreach (var higherFramework in higherFrameworks)
                    {
                        if (higherFramework.SupportedVersion != null && higherFramework.SupportedVersion > supportedVersion)
                        {
                            // found an higher framework version a higher API version, stop applying this supported version
                            break;
                        }

                        higherFramework.SupportedVersion = supportedVersion;
                    }
                }
            }


            // determine which Frameworks should support inbox
            _index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
            foreach (var inboxPair in _index.GetInboxVersions(ContractName).NullAsEmpty())
            {
                var fx           = inboxPair.Key;
                var inboxVersion = inboxPair.Value;

                if (inboxVersion != null)
                {
                    ValidationFramework validationFramework = null;
                    if (_frameworks.TryGetValue(fx, out validationFramework))
                    {
                        Version supportedVersion = validationFramework.SupportedVersion;

                        if (supportedVersion != null &&
                            (supportedVersion.Major > inboxVersion.Major ||
                             (supportedVersion.Major == inboxVersion.Major && supportedVersion.Minor > inboxVersion.Minor)))
                        {
                            // Higher major.minor
                            Log.LogMessage(LogImportance.Low, $"Framework {fx} supported {ContractName} as inbox but the current supported version {supportedVersion} is higher in major.minor than inbox version {inboxVersion}.  Assuming out of box.");
                            continue;
                        }
                        else if (supportedVersion != null && supportedVersion < inboxVersion && inboxVersion != VersionUtility.MaxVersion)
                        {
                            // Lower version
                            Log.LogError($"Framework {fx} supports {ContractName} as inbox but the current supported version {supportedVersion} is lower than the inbox version {inboxVersion}");
                        }

                        // equal major.minor, build.revision difference is permitted, prefer the version listed by ContractSupport item
                    }

                    if (validationFramework == null)
                    {
                        // we may not be explicitly validating for this framework so add it to validate inbox assets.
                        _frameworks[fx] = validationFramework = new ValidationFramework(fx)
                        {
                            SupportedVersion = inboxVersion
                        };
                    }

                    validationFramework.IsInbox = true;
                }
            }

            // for every framework we know about, also infer it's netstandard version to ensure it can
            // be targeted by PCL.  Even if a package only supports a single framework we still
            // want to include a portable reference assembly.  This allows 3rd parties to add
            // their own implementation via a lineup/runtime.json.

            // only consider frameworks that support the contract at a specific version
            var inferFrameworks = _frameworks.Values.Where(fx => fx.SupportedVersion != null && fx.SupportedVersion != VersionUtility.MaxVersion).ToArray();

            var genVersionSuppression       = GetSuppressionValues(Suppression.PermitPortableVersionMismatch) ?? new HashSet <string>();
            var inferNETStandardSuppression = GetSuppressionValues(Suppression.SuppressNETStandardInference) ?? new HashSet <string>();
            Dictionary <NuGetFramework, ValidationFramework> generationsToValidate = new Dictionary <NuGetFramework, ValidationFramework>();

            foreach (var inferFramework in inferFrameworks)
            {
                var inferFrameworkMoniker = inferFramework.Framework.ToString();
                if (inferNETStandardSuppression.Contains(inferFrameworkMoniker))
                {
                    continue;
                }

                NuGetFramework generation = new NuGetFramework(_generationIdentifier, Generations.DetermineGenerationForFramework(inferFramework.Framework, UseNetPlatform));
                Log.LogMessage(LogImportance.Low, $"Validating {generation} for {ContractName}, {inferFramework.SupportedVersion} since it is supported by {inferFrameworkMoniker}");

                ValidationFramework existingGeneration = null;
                if (generationsToValidate.TryGetValue(generation, out existingGeneration))
                {
                    // the netstandard version should be the minimum version supported by all platforms that support that netstandard version.
                    if (inferFramework.SupportedVersion < existingGeneration.SupportedVersion)
                    {
                        Log.LogMessage($"Framework {inferFramework.Framework} supports {ContractName} at {inferFramework.SupportedVersion} which is lower than {existingGeneration.SupportedVersion} supported by generation {generation.GetShortFolderName()}.  Lowering the version supported by {generation.GetShortFolderName()}.");
                        existingGeneration.SupportedVersion = inferFramework.SupportedVersion;
                    }
                }
                else
                {
                    generationsToValidate.Add(generation, new ValidationFramework(generation)
                    {
                        SupportedVersion = inferFramework.SupportedVersion
                    });
                }
            }

            foreach (var generation in generationsToValidate)
            {
                _frameworks.Add(generation.Key, generation.Value);
            }
        }
Example #25
0
        /// <summary>
        /// Merges another packageIndex into this package index.  For any overlapping
        /// data 'other' has precedence.
        /// </summary>
        /// <param name="other"></param>
        public void Merge(PackageIndex other)
        {
            if (other.IndexSources.IsSubsetOf(IndexSources))
            {
                return;
            }

            // if pre-release is set on this index and different than the other
            // move pre-release to individual infos
            if (PreRelease != null && !PreRelease.Equals(other.PreRelease))
            {
                foreach(var info in Packages.Values)
                {
                    if (info.PreRelease == null)
                    {
                        info.PreRelease = PreRelease;
                    }
                }

                PreRelease = null;
            }

            foreach(var otherPackage in other.Packages)
            {
                var otherInfo = otherPackage.Value;
                PackageInfo info;

                if (Packages.TryGetValue(otherPackage.Key, out info))
                {
                    info.Merge(otherInfo);
                }
                else
                {
                    Packages[otherPackage.Key] = info = otherInfo;
                }

                // if pre-release is set on the other index and doesn't match the value of the info, set it
                if (other.PreRelease != null && !other.PreRelease.Equals(info.PreRelease))
                {
                    info.PreRelease = other.PreRelease;
                }
            }

            foreach(var otherModuleToPackage in other.ModulesToPackages)
            {
                ModulesToPackages[otherModuleToPackage.Key] = otherModuleToPackage.Value;
            }

            foreach(var otherIndexSource in other.IndexSources)
            {
                IndexSources.Add(otherIndexSource);
            }
        }
Example #26
0
        private void LoadFrameworks()
        {
            _frameworks = new Dictionary <NuGetFramework, string[]>(NuGetFramework.Comparer);

            // load the specified frameworks
            foreach (var framework in Frameworks)
            {
                var runtimeIds = framework.GetMetadata("RuntimeIDs")?.Split(';');

                NuGetFramework fx;
                try
                {
                    fx = FrameworkUtilities.ParseNormalized(framework.ItemSpec);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse Framework {framework.ItemSpec}. {ex}");
                    continue;
                }

                if (fx.Equals(NuGetFramework.UnsupportedFramework))
                {
                    Log.LogError($"Did not recognize {framework.ItemSpec} as valid Framework.");
                    continue;
                }

                _frameworks.Add(fx, runtimeIds);
            }

            // inspect any TFMs explicitly targeted
            var fileFrameworks = _targetPathToPackageItem.Values.Select(f => f.TargetFramework).Distinct(NuGetFramework.Comparer).Where(f => f != null);

            foreach (var fileFramework in fileFrameworks)
            {
                if (!_frameworks.ContainsKey(fileFramework))
                {
                    _frameworks.Add(fileFramework, s_noRids);
                }
            }

            // inspect any TFMs inbox
            var index           = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
            var inboxFrameworks = index.GetInboxFrameworks(PackageId).NullAsEmpty();

            foreach (var inboxFramework in inboxFrameworks)
            {
                if (!_frameworks.ContainsKey(inboxFramework))
                {
                    _frameworks.Add(inboxFramework, s_noRids);
                }
            }

            // inspect for derived TFMs
            var expander = new FrameworkExpander();

            foreach (var framework in _frameworks.Keys.ToArray())
            {
                var derivedFxs = expander.Expand(framework);

                foreach (var derivedFx in derivedFxs)
                {
                    if (derivedFx.IsDesktop() && derivedFx.HasProfile)
                    {
                        // skip desktop profiles
                        continue;
                    }

                    if (derivedFx.Version.Major == 0 && derivedFx.Version.Minor == 0)
                    {
                        // skip unversioned frameworks
                        continue;
                    }

                    if (s_ignoredFrameworks.Contains(derivedFx.Framework))
                    {
                        continue;
                    }

                    if (!_frameworks.ContainsKey(derivedFx))
                    {
                        _frameworks.Add(derivedFx, s_noRids);
                    }
                }
            }
        }
Example #27
0
        private void UpdateFromValues(PackageIndex index, string id, NuGetVersion version, IEnumerable<Version> assemblyVersions, IEnumerable<string> dllNames)
        {
            PackageInfo info = GetOrCreatePackageInfo(index, id);

            var packageVersion = VersionUtility.As3PartVersion(version.Version);
            // if we have a stable version, add it to the stable versions list
            if (!version.IsPrerelease)
            {
                info.StableVersions.Add(packageVersion);
            }

            var assmVersions = new HashSet<Version>(assemblyVersions.NullAsEmpty().Where(v => v != null));

            // add any new assembly versions
            info.AddAssemblyVersionsInPackage(assmVersions, packageVersion);

            // try to find an identity package to also add a mapping in the case this is a runtime package
            if (id.StartsWith("runtime."))
            {
                foreach (var dllName in dllNames)
                {
                    PackageInfo identityInfo;
                    if (index.Packages.TryGetValue(dllName, out identityInfo))
                    {
                        identityInfo.AddAssemblyVersionsInPackage(assmVersions, packageVersion);
                    }
                }
            }

            // remove any assembly mappings which claim to be in this package version, but aren't in the assemblyList
            var orphanedAssemblyVersions = info.AssemblyVersionInPackageVersion
                                                .Where(pair => pair.Value == packageVersion && !assmVersions.Contains(pair.Key))
                                                .Select(pair => pair.Key);

            if (orphanedAssemblyVersions.Any())
            {
                // make sure these aren't coming from a runtime package.
                var runtimeAssemblyVersions = index.Packages
                    .Where(p => p.Key.StartsWith("runtime.") && p.Key.EndsWith(id))
                    .SelectMany(p => p.Value.AssemblyVersionInPackageVersion)
                    .Where(pair => pair.Value == packageVersion)
                    .Select(pair => pair.Key);

                orphanedAssemblyVersions = orphanedAssemblyVersions.Except(runtimeAssemblyVersions);
            }

            foreach (var orphanedAssemblyVersion in orphanedAssemblyVersions.ToArray())
            {
                info.AssemblyVersionInPackageVersion.Remove(orphanedAssemblyVersion);
            }

            // if no assemblies are present in this package nor were ever present
            if (assmVersions.Count == 0 &&
                info.AssemblyVersionInPackageVersion.Count == 0)
            {
                // if in the native module map
                if (index.ModulesToPackages.Values.Any(p => p.Equals(id)))
                {
                    // ensure the baseline is set
                    info.BaselineVersion = packageVersion;
                }
            }
        }
Example #28
0
        /* Given a set of available frameworks ("InboxOnTargetFrameworks"), and a list of desired frameworks,
         * reduce the set of frameworks to the minimum set of frameworks which is compatible (preferring inbox frameworks. */
        public override bool Execute()
        {
            if (null == Dependencies)
            {
                Log.LogError("Dependencies argument must be specified");
                return(false);
            }
            if (PackageIndexes == null && PackageIndexes.Length == 0)
            {
                Log.LogError("PackageIndexes argument must be specified");
                return(false);
            }

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            // Retrieve the list of generation dependency group TFM's
            var dependencyGroups = Dependencies.GroupBy(d => d.GetMetadata("TargetFramework")).Select(dg => new
            {
                Framework    = NuGetFramework.Parse(dg.Key),
                Dependencies = dg.ToArray()
            });

            List <ITaskItem> addedDependencies = new List <ITaskItem>();

            // Exclude any non-portable frameworks that already have specific dependency groups.
            var frameworksToExclude = dependencyGroups.Select(dg => dg.Framework).Where(fx => !FrameworkUtilities.IsGenerationMoniker(fx));

            // Prepare a resolver for evaluating if candidate frameworks are actually supported by the package
            PackageItem[] packageItems = Files.Select(f => new PackageItem(f)).ToArray();
            var           packagePaths = packageItems.Select(pi => pi.TargetPath);
            var           targetFrameworksWithPlaceHolders = packageItems.Where(pi => NuGetAssetResolver.IsPlaceholder(pi.TargetPath)).Select(pi => pi.TargetFramework);

            NuGetAssetResolver resolver = new NuGetAssetResolver(null, packagePaths);

            foreach (var portableDependencyGroup in dependencyGroups.Where(dg => FrameworkUtilities.IsGenerationMoniker(dg.Framework)))
            {
                // Determine inbox frameworks for this generation that don't already have explicit groups
                HashSet <NuGetFramework> inboxFrameworksList = new HashSet <NuGetFramework>(
                    index.GetAlllInboxFrameworks()
                    .Where(fx => Generations.DetermineGenerationForFramework(fx, UseNetPlatform) >= portableDependencyGroup.Framework.Version &&
                           !frameworksToExclude.Any(exFx => exFx.Framework == fx.Framework && exFx.Profile == fx.Profile && exFx.Version <= fx.Version)));

                // Check for assets which have a ref, but not a lib asset. If we have any of these, then they are actually not supported frameworks
                // and we should not include them.
                inboxFrameworksList.RemoveWhere(inboxFx => !IsSupported(inboxFx, resolver));

                // Only add the lowest version for a particular inbox framework.  EG if both net45 and net46 are supported by this generation,
                //        only add net45
                inboxFrameworksList.RemoveWhere(fx => inboxFrameworksList.Any(otherFx => (otherFx.Framework.Equals(fx.Framework)) && (otherFx.Version < fx.Version)));

                // Create dependency items for each inbox framework.
                foreach (var framework in inboxFrameworksList)
                {
                    bool addedDependencyToFramework = false;
                    foreach (ITaskItem dependency in portableDependencyGroup.Dependencies)
                    {
                        string version = GetVersion(dependency);

                        if (!index.IsInbox(dependency.ItemSpec, framework, version))
                        {
                            addedDependencyToFramework = true;
                            AddDependency(addedDependencies, new TaskItem(dependency), framework, portableDependencyGroup.Framework);
                        }
                    }
                    if (!addedDependencyToFramework)
                    {
                        AddDependency(addedDependencies, new TaskItem("_._"), framework, portableDependencyGroup.Framework);
                    }
                }
            }

            // Collapse frameworks
            // For any dependency with a targetframework, if there is another target framework which is compatible and older, remove this dependency.

            // Get all Dependencies which are not in a portable dependency group so that we can collapse the frameworks.  If we include
            // the portable frameworks, then we'll end up collapsing to those.
            List <NuGetFramework> allDependencyGroups = new List <NuGetFramework>();

            allDependencyGroups.AddRange(Dependencies.Select(d => NuGetFramework.Parse(d.GetMetadata("TargetFramework"))).Where(a => !allDependencyGroups.Contains(a) &&
                                                                                                                                !FrameworkUtilities.IsGenerationMoniker(a) &&
                                                                                                                                !FrameworkUtilities.IsPortableMoniker(a)));
            allDependencyGroups.AddRange(addedDependencies.Select(d => NuGetFramework.Parse(d.GetMetadata("TargetFramework"))).Where(a => !allDependencyGroups.Contains(a) &&
                                                                                                                                     !FrameworkUtilities.IsGenerationMoniker(a) &&
                                                                                                                                     !FrameworkUtilities.IsPortableMoniker(a)));

            List <NuGetFramework> collapsedDependencyGroups = FrameworkUtilities.ReduceDownwards(allDependencyGroups).ToList <NuGetFramework>();

            // Get the list of dependency groups that we collapsed down so that we can add them back if they contained different dependencies than what is present in the collapsed group.

            /* TODO: Look into NuGet's sorting algorithm, they may have a bug (fixed in this line). They were not including version in the sort.
             *       See ReduceCore in https://github.com/NuGet/NuGet.Client/blob/23ea68b91a439fcfd7f94bcd01bcdee2e8adae92/src/NuGet.Core/NuGet.Frameworks/FrameworkReducer.cs */
            IEnumerable <NuGetFramework> removedDependencyGroups = allDependencyGroups.Where(d => !collapsedDependencyGroups.Contains(d))?.OrderBy(f => f.Framework, StringComparer.OrdinalIgnoreCase).ThenBy(f => f.Version);

            foreach (NuGetFramework removedDependencyGroup in removedDependencyGroups)
            {
                // always recalculate collapsedDependencyGroups in case we added an item in a previous iteration.  Dependency groups are sorted, so this should be additive and we shouldn't need to restart the collapse / add back cycle
                var nearest = FrameworkUtilities.GetNearest(removedDependencyGroup, collapsedDependencyGroups.ToArray());

                // gather the dependencies for this dependency group and the calculated "nearest" dependency group
                var nearestDependencies = addedDependencies.Where(d => nearest.Equals(NuGetFramework.Parse(d.GetMetadata("TargetFramework")))).OrderBy(f => f.ToString());
                var currentDependencies = addedDependencies.Where(d => removedDependencyGroup.Equals(NuGetFramework.Parse(d.GetMetadata("TargetFramework")))).OrderBy(f => f.ToString());

                // The nearest dependency group's dependencies are different than this dependency group's dependencies
                if (nearestDependencies.Count() != currentDependencies.Count())
                {
                    // ignore if dependency is a placeholder
                    if (currentDependencies.Count() > 0)
                    {
                        if (!NuGetAssetResolver.IsPlaceholder(currentDependencies.First().ToString()))
                        {
                            collapsedDependencyGroups.Add(removedDependencyGroup);
                        }
                    }
                    else
                    {
                        collapsedDependencyGroups.Add(removedDependencyGroup);
                    }
                }
                // identical dependency count between current and nearest, and the count is > 0
                else if (nearestDependencies.Count() > 0)
                {
                    if (!currentDependencies.SequenceEqual(nearestDependencies, new DependencyITaskItemComparer()))
                    {
                        collapsedDependencyGroups.Add(removedDependencyGroup);
                    }
                }
            }


            List <ITaskItem> collapsedDependencies = new List <ITaskItem>();

            foreach (ITaskItem dependency in addedDependencies)
            {
                if (collapsedDependencyGroups.Contains(NuGetFramework.Parse(dependency.GetMetadata("TargetFramework"))))
                {
                    collapsedDependencies.Add(dependency);
                }
            }
            TrimmedDependencies = collapsedDependencies.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #29
0
        private void ValidateIndex()
        {
            if (SkipIndexCheck)
            {
                return;
            }

            if (PackageIndexes == null || PackageIndexes.Length == 0)
            {
                return;
            }

            var index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));

            PackageInfo info;

            if (!index.Packages.TryGetValue(PackageId, out info))
            {
                Log.LogError($"PackageIndex from {String.Join(", ", PackageIndexes.Select(i => i.ItemSpec))} is missing an entry for package {PackageId}.  Please run /t:UpdatePackageIndex on this project to commit an update.");
                return;
            }

            var allDlls          = _report.Targets.Values.SelectMany(t => t.CompileAssets.NullAsEmpty().Concat(t.RuntimeAssets.NullAsEmpty()));
            var allAssemblies    = allDlls.Where(f => f.Version != null);
            var assemblyVersions = new HashSet <Version>(allAssemblies.Select(f => VersionUtility.As4PartVersion(f.Version)));

            var thisPackageVersion = VersionUtility.As3PartVersion(NuGetVersion.Parse(PackageVersion).Version);

            foreach (var fileVersion in assemblyVersions)
            {
                Version packageVersion;

                // determine if we're missing a mapping for this package
                if (!info.AssemblyVersionInPackageVersion.TryGetValue(fileVersion, out packageVersion))
                {
                    Log.LogError($"PackageIndex from {String.Join(", ", PackageIndexes.Select(i => i.ItemSpec))} is missing an assembly version entry for {fileVersion} for package {PackageId}.  Please run /t:UpdatePackageIndex on this project to commit an update.");
                }
                else
                {
                    // determine if we have a mapping for an unstable package and that unstable package is not this one
                    if (!info.StableVersions.Contains(packageVersion) && packageVersion != thisPackageVersion)
                    {
                        Log.LogError($"PackageIndex from {String.Join(", ", PackageIndexes.Select(i => i.ItemSpec))} indicates that assembly version {fileVersion} is contained in non-stable package version {packageVersion} which differs from this package version {thisPackageVersion}.");
                    }
                }
            }

            var orphanedAssemblyVersions = info.AssemblyVersionInPackageVersion
                                           .Where(pair => pair.Value == thisPackageVersion && !assemblyVersions.Contains(pair.Key))
                                           .Select(pair => pair.Key);

            if (orphanedAssemblyVersions.Any())
            {
                Log.LogError($"PackageIndex from {String.Join(", ", PackageIndexes.Select(i => i.ItemSpec))} is has an assembly version entry(s) for {String.Join(", ", orphanedAssemblyVersions)} which are no longer in package {PackageId}.  Please run /t:UpdatePackageIndex on this project to commit an update.");
            }

            // if no assemblies are present in this package nor were ever present
            if (assemblyVersions.Count == 0 &&
                info.AssemblyVersionInPackageVersion.Count == 0)
            {
                // if in the native module map
                if (index.ModulesToPackages.Values.Any(p => p.Equals(PackageId)))
                {
                    // ensure the baseline is set
                    if (info.BaselineVersion != thisPackageVersion)
                    {
                        Log.LogError($"PackageIndex from {String.Join(", ", PackageIndexes.Select(i => i.ItemSpec))} is missing an baseline entry(s) for native module {PackageId}.  Please run /t:UpdatePackageIndex on this project to commit an update.");
                    }
                }
                else
                {
                    // not in the native module map, see if any of the modules in this package are present
                    // (with a different package, as would be the case for runtime-specific packages)
                    var moduleNames        = allDlls.Select(d => Path.GetFileNameWithoutExtension(d.LocalPath));
                    var missingModuleNames = moduleNames.Where(m => !index.ModulesToPackages.ContainsKey(m));
                    if (missingModuleNames.Any())
                    {
                        Log.LogError($"PackageIndex from {String.Join(", ", PackageIndexes.Select(i => i.ItemSpec))} is missing ModulesToPackages entry(s) for {String.Join(", ", missingModuleNames)} to package {PackageId}.  Please add a an entry for the appropriate package.");
                    }
                }
            }
        }
Example #30
0
        private void UpdateFromValues(PackageIndex index, string id, NuGetVersion version, IEnumerable <Version> assemblyVersions, IEnumerable <string> dllNames)
        {
            PackageInfo info = GetOrCreatePackageInfo(index, id);

            var packageVersion = VersionUtility.As3PartVersion(version.Version);

            // if we have a stable version, add it to the stable versions list
            if (!version.IsPrerelease)
            {
                info.StableVersions.Add(packageVersion);
            }

            var assmVersions = new HashSet <Version>(assemblyVersions.NullAsEmpty().Where(v => v != null));

            // add any new assembly versions
            info.AddAssemblyVersionsInPackage(assmVersions, packageVersion);

            // try to find an identity package to also add a mapping in the case this is a runtime package
            if (id.StartsWith("runtime."))
            {
                foreach (var dllName in dllNames)
                {
                    PackageInfo identityInfo;
                    if (index.Packages.TryGetValue(dllName, out identityInfo))
                    {
                        identityInfo.AddAssemblyVersionsInPackage(assmVersions, packageVersion);
                    }
                }
            }

            // remove any assembly mappings which claim to be in this package version, but aren't in the assemblyList
            var orphanedAssemblyVersions = info.AssemblyVersionInPackageVersion
                                           .Where(pair => pair.Value == packageVersion && !assmVersions.Contains(pair.Key))
                                           .Select(pair => pair.Key);

            if (orphanedAssemblyVersions.Any())
            {
                // make sure these aren't coming from a runtime package.
                var runtimeAssemblyVersions = index.Packages
                                              .Where(p => p.Key.StartsWith("runtime.") && p.Key.EndsWith(id))
                                              .SelectMany(p => p.Value.AssemblyVersionInPackageVersion)
                                              .Where(pair => pair.Value == packageVersion)
                                              .Select(pair => pair.Key);

                orphanedAssemblyVersions = orphanedAssemblyVersions.Except(runtimeAssemblyVersions);
            }

            foreach (var orphanedAssemblyVersion in orphanedAssemblyVersions.ToArray())
            {
                info.AssemblyVersionInPackageVersion.Remove(orphanedAssemblyVersion);
            }

            // if no assemblies are present in this package nor were ever present
            if (assmVersions.Count == 0 &&
                info.AssemblyVersionInPackageVersion.Count == 0)
            {
                // if in the native module map
                if (index.ModulesToPackages.Values.Any(p => p.Equals(id)))
                {
                    // ensure the baseline is set
                    info.BaselineVersion = packageVersion;
                }
            }
        }
Example #31
0
        private void UpdateFromPackage(PackageIndex index, string packagePath, bool filter = false)
        {
            string id;
            NuGetVersion version;
            IEnumerable<Version> assemblyVersions;
            IEnumerable<string> dllNames;

            using (var reader = new PackageArchiveReader(packagePath))
            {
                var identity = reader.GetIdentity();
                id = identity.Id;
                version = identity.Version;

                if (filter && !ShouldInclude(id))
                {
                    return;
                }

                var dlls = reader.GetFiles().Where(f => Path.GetExtension(f).Equals(".dll", StringComparison.OrdinalIgnoreCase));

                assemblyVersions = dlls.Select(refFile =>
                {
                    using (var refStream = reader.GetStream(refFile))
                    using (var memStream = new MemoryStream())
                    {
                        refStream.CopyTo(memStream);
                        memStream.Seek(0, SeekOrigin.Begin);
                        return VersionUtility.GetAssemblyVersion(memStream);
                    }
                }).ToArray();

                dllNames = dlls.Select(f => Path.GetFileNameWithoutExtension(f)).Distinct().ToArray();
            }

            UpdateFromValues(index, id, version, assemblyVersions, dllNames);
        }
Example #32
0
        public override bool Execute()
        {
            string indexFilePath = PackageIndexFile.GetMetadata("FullPath");

            PackageIndex index = File.Exists(indexFilePath) ?
                                 index = PackageIndex.Load(indexFilePath) :
                                         new PackageIndex();

            if (PackageIds != null && PackageIds.Any())
            {
                _packageIdsToInclude = new HashSet <string>(PackageIds.Select(i => i.ItemSpec), StringComparer.OrdinalIgnoreCase);
            }

            foreach (var package in Packages.NullAsEmpty().Select(f => f.GetMetadata("FullPath")))
            {
                Log.LogMessage($"Updating from {package}.");
                UpdateFromPackage(index, package);
            }

            foreach (var packageFolder in PackageFolders.NullAsEmpty().Select(f => f.GetMetadata("FullPath")))
            {
                var nupkgs = Directory.EnumerateFiles(packageFolder, "*.nupkg", SearchOption.TopDirectoryOnly);

                if (nupkgs.Any())
                {
                    foreach (var nupkg in nupkgs)
                    {
                        Log.LogMessage($"Updating from {nupkg}.");
                        UpdateFromPackage(index, nupkg, true);
                    }
                }
                else
                {
                    var nuspecFolders = Directory.EnumerateFiles(packageFolder, "*.nuspec", SearchOption.AllDirectories)
                                        .Select(nuspec => Path.GetDirectoryName(nuspec));

                    foreach (var nuspecFolder in nuspecFolders)
                    {
                        Log.LogMessage($"Updating from {nuspecFolder}.");
                        UpdateFromFolderLayout(index, nuspecFolder, true);
                    }
                }
            }

            if (BaselinePackages != null)
            {
                foreach (var baselinePackage in BaselinePackages)
                {
                    var info    = GetOrCreatePackageInfo(index, baselinePackage.ItemSpec);
                    var version = baselinePackage.GetMetadata("Version");

                    info.BaselineVersion = Version.Parse(version);
                }
            }

            if (StablePackages != null)
            {
                foreach (var stablePackage in StablePackages)
                {
                    var info    = GetOrCreatePackageInfo(index, stablePackage.ItemSpec);
                    var version = stablePackage.GetMetadata("Version");

                    info.StableVersions.Add(Version.Parse(version));
                }
            }

            if (ModuleToPackages != null)
            {
                foreach (var moduleToPackage in ModuleToPackages)
                {
                    var package = moduleToPackage.GetMetadata("Package");
                    index.ModulesToPackages[moduleToPackage.ItemSpec] = package;
                }
            }

            if (!String.IsNullOrEmpty(PreRelease))
            {
                index.PreRelease = PreRelease;
            }

            index.Save(indexFilePath);

            return(!Log.HasLoggedErrors);
        }
Example #33
0
        private void UpdateFromFolderLayout(PackageIndex index, string path, bool filter = false)
        {
            var version = NuGetVersion.Parse(Path.GetFileName(path));
            var id = Path.GetFileName(Path.GetDirectoryName(path));

            if (filter && !ShouldInclude(id))
            {
                return;
            }

            var dlls = Directory.EnumerateFiles(path, "*.dll", SearchOption.AllDirectories);

            var assemblyVersions = dlls.Select(f => VersionUtility.GetAssemblyVersion(f));
            var dllNames = dlls.Select(f => Path.GetFileNameWithoutExtension(f)).Distinct();

            UpdateFromValues(index, id, version, assemblyVersions, dllNames);
        }
 private void LoadIndex()
 {
     _index = PackageIndex.Load(PackageIndexes.Select(pi => pi.GetMetadata("FullPath")));
 }
Example #35
0
        private PackageInfo GetOrCreatePackageInfo(PackageIndex index, string id)
        {
            PackageInfo info;

            if (!index.Packages.TryGetValue(id, out info))
            {
                index.Packages[id] = info = new PackageInfo();
            }

            return info;
        }