/// <summary>
        /// Sorts the specified list of packages according to their dependencies, guaranteeing that no package
        /// is listed before its dependencies. Use this to determine the order of batch updates and installs
        /// to prevent conflicts from having different versions of the same packages.
        /// </summary>
        public void OrderByDependencies(IList <LocalPackage> packages)
        {
            // Map each list entry to its PackageInfo
            PackageInfo[] localInfo = packages
                                      .Select(p => p.Info ?? this.GetPackage(p.Name))
                                      .NotNull()
                                      .ToArray();

            // Sort the mapped list
            this.OrderByDependencies(localInfo);

            // Now sort the original list to match the sorted mapped list
            LocalPackage[] originalPackages = packages.ToArray();
            int            nonSortedCount   = 0;

            for (int i = 0; i < originalPackages.Length; i++)
            {
                LocalPackage localPackage = originalPackages[i];

                int newIndex = localInfo.IndexOfFirst(p => p.Id == localPackage.Id && p.Version == localPackage.Version);
                if (newIndex == -1)
                {
                    newIndex = localInfo.IndexOfFirst(p => p.Id == localPackage.Id);
                }

                // Unresolved packages are always last in the sorted list
                if (newIndex == -1)
                {
                    newIndex = packages.Count - nonSortedCount - 1;
                    nonSortedCount++;
                }

                packages[newIndex] = localPackage;
            }
        }
Exemple #2
0
        /// <summary>
        /// Determines whether all installed pacakges are forward compatible to <paramref name="target"/>.
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public PackageCompatibility GetForwardCompatibility(PackageInfo target)
        {
            LocalPackage current = this.localPackages.FirstOrDefault(p => p.Id == target.Id);

            if (current == null)
            {
                return(PackageCompatibility.Definite);
            }

            Version currentVersion = current.Version;
            Version targetVersion  = target.Version;

            // ToDo: Implement a more sophisticated algorithm

            if (currentVersion.Major != targetVersion.Major)
            {
                return(PackageCompatibility.Unlikely);
            }
            else if (currentVersion.Minor != targetVersion.Minor)
            {
                return(PackageCompatibility.Likely);
            }
            else
            {
                return(PackageCompatibility.Definite);
            }
        }
Exemple #3
0
        public void UpdatePackage(LocalPackage package)
        {
            this.uninstallQueue = null;
            PackageInfo newVersion = this.QueryPackageInfo(package.Id);

            this.manager.UpdatePackage(newVersion.Id, new SemanticVersion(newVersion.Version), true, false);
            this.uninstallQueue = new List <LocalPackage>();
        }
Exemple #4
0
        public void UpdatePackage(LocalPackage package, Version specificVersion = null)
        {
            // Due to a bug in NuGet 2.8.2, specific-version downgrades are limited to the package itself,
            // without updating its dependencies. Otherwise, some of them might be uninstalled without
            // being reinstalled properly.

            this.uninstallQueue = null;
            bool isDowngrade = specificVersion != null && specificVersion < package.Version;

            NuGet.IPackage newPackage = this.FindPackageInfo(new PackageName(package.Id, specificVersion), false);
            this.manager.UpdatePackage(newPackage, !isDowngrade, false);
            this.uninstallQueue = new List <LocalPackage>();
        }
Exemple #5
0
        public void UpdatePackage(LocalPackage package)
        {
            NuGet.IPackage newPackage = this.FindPackageInfo(new PackageName(package.Id));

            // Check license terms
            if (!this.CheckDeepLicenseAgreements(newPackage))
            {
                return;
            }

            this.uninstallQueue = null;
            this.manager.UpdatePackage(newPackage, true, false);
            this.uninstallQueue = new List <LocalPackage>();
        }
Exemple #6
0
        public bool CanUninstallPackage(LocalPackage package)
        {
            bool allowed = true;

            this.manager.WhatIf = true;
            try
            {
                this.manager.UninstallPackage(package.Id, new SemanticVersion(package.Version), false, true);
            }
            catch (Exception)
            {
                allowed = false;
            }
            this.manager.WhatIf = false;
            return(allowed);
        }
Exemple #7
0
        public void OrderByDependencies(IList <LocalPackage> packages)
        {
            // Map each list entry to its PackageInfo
            PackageInfo[] localInfo = packages.Select(p => p.Info ?? this.QueryPackageInfo(p.PackageName)).ToArray();

            // Sort the mapped list
            this.OrderByDependencies(localInfo);

            // Now sort the original list to match the sorted mapped list
            LocalPackage[] originalPackages = packages.ToArray();
            for (int i = 0; i < originalPackages.Length; i++)
            {
                LocalPackage localPackage = originalPackages[i];
                int          newIndex     = localInfo.IndexOfFirst(p => p.Id == localPackage.Id && p.Version == localPackage.Version);
                packages[newIndex] = localPackage;
            }
        }
        /// <summary>
        /// Installs the specified package if it wasn't installed yet and synchronizes
        /// the registered Duality package version number with the one that is present
        /// in the local cache.
        /// </summary>
        /// <param name="localPackage"></param>
        public void VerifyPackage(LocalPackage localPackage)
        {
            Version oldPackageVersion = localPackage.Version;

            // Determine the exact version that will be installed
            PackageInfo packageInfo = this.GetPackage(localPackage.Name);

            if (packageInfo == null)
            {
                throw new Exception(string.Format(
                                        "Can't resolve version of package '{0}'. There seems to be no compatible version available.",
                                        localPackage.Id));
            }

            // Prepare a listener to determine whether we actually installed something
            EventHandler <PackageOperationEventArgs> installListener = null;
            bool packageInstalled = false;

            installListener = delegate(object sender, PackageOperationEventArgs args)
            {
                if (args.Package.Id == localPackage.Id)
                {
                    packageInstalled = true;
                }
            };

            // Install the package. Won't do anything if the package is already installed.
            this.manager.PackageInstalled += installListener;
            this.InstallPackage(localPackage.Name, true);
            this.manager.PackageInstalled -= installListener;

            // If we didn't install anything, that package was already in the local repo.
            // Update the local setup to match its specific version.
            if (!packageInstalled && oldPackageVersion == null)
            {
                // Add the explicit version to the PackageConfig file
                this.setup.Packages.RemoveAll(p => p.Id == packageInfo.Id);
                this.setup.Packages.Add(new LocalPackage(packageInfo));
            }

            // In case we've just retrieved an explicit version for the first time, save the config file.
            if (oldPackageVersion == null)
            {
                this.setup.Save(this.env.ConfigFilePath);
            }
        }
Exemple #9
0
        public bool CanUpdatePackage(LocalPackage package)
        {
            bool allowed = true;

            this.manager.WhatIf = true;
            try
            {
                Version version = this.QueryPackageInfo(package.PackageName.VersionInvariant).Version;
                this.manager.UpdatePackage(package.Id, new SemanticVersion(version), true, false);
            }
            catch (Exception)
            {
                allowed = false;
            }
            this.manager.WhatIf = false;
            return(allowed);
        }
Exemple #10
0
        /// <summary>
        /// Determines compatibility between the current package installs and the specified target package.
        /// Works for both updates and new installs.
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public PackageCompatibility GetCompatibilityLevel(PackageInfo target)
        {
            // If the target package is already installed in the matching version, assume compatibility
            if (this.localPackages.Any(local => local.Id == target.Id && local.Version == target.Version))
            {
                return(PackageCompatibility.Definite);
            }

            // Determine all packages that might be updated or installed
            PackageInfo[] touchedPackages = this.GetDeepDependencies(new[] { target }).ToArray();

            // Generate a mapping to already installed packages
            Dictionary <PackageInfo, LocalPackage> localMap = new Dictionary <PackageInfo, LocalPackage>();

            foreach (PackageInfo package in touchedPackages)
            {
                LocalPackage local = this.localPackages.FirstOrDefault(p => p.Id == package.Id);
                if (local == null)
                {
                    continue;
                }

                localMap.Add(package, local);
            }

            // Determine the maximum version difference between target and installed
            PackageCompatibility compatibility = PackageCompatibility.Definite;

            foreach (var pair in localMap)
            {
                Version targetVersion = pair.Key.Version;
                Version localVersion  = pair.Value.Version;

                if (localVersion.Major != targetVersion.Major)
                {
                    compatibility = compatibility.Combine(PackageCompatibility.Unlikely);
                }
                else if (localVersion.Minor != targetVersion.Minor)
                {
                    compatibility = compatibility.Combine(PackageCompatibility.Likely);
                }
            }

            return(compatibility);
        }
Exemple #11
0
        public void VerifyPackage(LocalPackage package)
        {
            Version oldPackageVersion = package.Version;

            // Determine the exact version that will be downloaded
            PackageInfo packageInfo = this.QueryPackageInfo(package.Id, package.Version);

            if (packageInfo == null)
            {
                throw new ApplicationException(string.Format(
                                                   "Can't resolve version of package '{0}'. There seems to be no compatible version available.",
                                                   package.Id));
            }

            // Prepare a listener to determine whether we actually installed something
            EventHandler <PackageOperationEventArgs> installListener = null;
            bool packageInstalled = false;

            installListener = delegate(object sender, PackageOperationEventArgs args)
            {
                if (args.Package.Id == package.Id)
                {
                    packageInstalled = true;
                }
            };

            // Install the package. Won't do anything if the package is already installed.
            this.manager.PackageInstalled += installListener;
            this.InstallPackage(packageInfo);
            this.manager.PackageInstalled -= installListener;

            // If we didn't install anything, that package was already present in the local cache, but not in the PackageConfig file
            if (!packageInstalled && oldPackageVersion == null)
            {
                // Add the explicit version to the PackageConfig file
                this.localPackages.RemoveAll(p => p.Id == packageInfo.Id);
                this.localPackages.Add(new LocalPackage(packageInfo));
            }

            // In case we've just retrieved an explicit version for the first time, save the config file.
            if (oldPackageVersion == null)
            {
                this.SaveConfig();
            }
        }
Exemple #12
0
        public bool CanUpdatePackage(LocalPackage package, Version specificVersion = null)
        {
            bool allowed = true;

            this.manager.WhatIf = true;
            try
            {
                bool isSpecific = specificVersion != null;
                if (specificVersion == null)
                {
                    specificVersion = this.QueryPackageInfo(package.PackageName.VersionInvariant).Version;
                }
                this.manager.UpdatePackage(package.Id, new SemanticVersion(specificVersion), !isSpecific, false);
            }
            catch (Exception)
            {
                allowed = false;
            }
            this.manager.WhatIf = false;
            return(allowed);
        }
Exemple #13
0
        public void VerifyPackage(LocalPackage package)
        {
            Version oldPackageVersion = package.Version;

            // Determine the exact version that will be downloaded
            PackageInfo packageInfo = this.QueryPackageInfo(package.Id, package.Version);

            if (packageInfo == null)
            {
                throw new ApplicationException(string.Format(
                                                   "Can't resolve version of package '{0}'. There seems to be no compatible version available.",
                                                   package.Id));
            }

            // Install the package. Won't do anything if the package is already installed.
            this.InstallPackage(packageInfo);

            // In case we've just retrieved an explicit version for the first time, save the config file.
            if (oldPackageVersion == null)
            {
                this.SaveConfig();
            }
        }
Exemple #14
0
		public LocalPackageItem(LocalPackage package, BaseItem parent) : base(package.Info, parent) {}
Exemple #15
0
        /// <summary>
        /// Determines the number of deep dependencies for the specified package.
        /// </summary>
        /// <param name="package"></param>
        /// <param name="deepCount"></param>
        /// <param name="resolver"></param>
        /// <returns></returns>
        private int GetDeepDependencyCount(PackageInfo package, Dictionary <PackageInfo, int> deepCount, Dictionary <PackageName, PackageInfo> resolveCache)
        {
            int count;

            if (!deepCount.TryGetValue(package, out count))
            {
                // Use the count of direct dependencies as starting value
                count = package.Dependencies.Count();

                // Prevent endless recursion on cyclic dependency graphs by registering early
                deepCount[package] = count;

                // Iterate over dependencies and count theirs as well
                foreach (PackageName dependencyName in package.Dependencies)
                {
                    // Try to resolve the dependency name to get a hold on the actual info
                    PackageInfo dependency;
                    if (!resolveCache.TryGetValue(dependencyName, out dependency))
                    {
                        // Try the exact name locally and online
                        dependency = this.QueryPackageInfo(dependencyName);

                        // If nothing turns up, see if we have a similar package locally and try that as well
                        if (dependency == null)
                        {
                            LocalPackage localDependency = this.localPackages.FirstOrDefault(p => p.Id == dependencyName.Id);
                            if (localDependency != null)
                            {
                                if (localDependency.Info != null)
                                {
                                    dependency = localDependency.Info;
                                }
                                else
                                {
                                    dependency = this.QueryPackageInfo(localDependency.PackageName);
                                }
                            }
                        }

                        // If we still have nothing, try a general search for the newest package with that Id
                        if (dependency == null)
                        {
                            dependency = this.QueryPackageInfo(dependencyName.VersionInvariant);
                        }

                        // Cache the results for later
                        resolveCache[dependencyName] = dependency;
                    }
                    if (dependency == null)
                    {
                        continue;
                    }

                    // Add secondary dependencies
                    count += GetDeepDependencyCount(dependency, deepCount, resolveCache);
                }

                // Update the registered value
                deepCount[package] = count;
            }
            return(count);
        }
Exemple #16
0
 public void UninstallPackage(LocalPackage package)
 {
     this.manager.UninstallPackage(package.Id, new SemanticVersion(package.Version), false, true);
 }
        /// <summary>
        /// Determines compatibility between the current package installs and the specified target package.
        /// Works for both updates and new installs.
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public PackageCompatibility GetCompatibilityLevel(PackageInfo target)
        {
            // If the target package is already installed in the matching version, assume compatibility
            if (this.setup.GetPackage(target.Id, target.Version) != null)
            {
                return(PackageCompatibility.Definite);
            }

            // Determine all packages that might be updated or installed
            this.dependencyWalker.Clear();
            this.dependencyWalker.WalkGraph(target);
            List <PackageInfo> touchedPackages = this.dependencyWalker.VisitedPackages.ToList();

            // Verify properly specified dependencies for Duality packages
            if (target.IsDualityPackage)
            {
                // If none of the targets deep dependencies is anyhow related to Duality, assume they're incomplete and potentially incompatible
                bool anyDualityDependency = false;
                foreach (PackageInfo package in touchedPackages)
                {
                    if (DualityPackageNames.Any(name => string.Equals(name, package.Id)))
                    {
                        anyDualityDependency = true;
                        break;
                    }
                }
                if (!anyDualityDependency)
                {
                    return(PackageCompatibility.None);
                }
            }

            // Generate a mapping to already installed packages
            Dictionary <PackageInfo, LocalPackage> localMap = new Dictionary <PackageInfo, LocalPackage>();

            foreach (PackageInfo package in touchedPackages)
            {
                LocalPackage local = this.setup.GetPackage(package.Id);
                if (local == null)
                {
                    continue;
                }

                localMap.Add(package, local);
            }

            // Determine the maximum version difference between target and installed
            PackageCompatibility compatibility = PackageCompatibility.Definite;

            foreach (var pair in localMap)
            {
                Version targetVersion = pair.Key.Version;
                Version localVersion  = pair.Value.Version;

                if (localVersion.Major != targetVersion.Major)
                {
                    compatibility = compatibility.Combine(PackageCompatibility.Unlikely);
                }
                else if (localVersion.Minor != targetVersion.Minor)
                {
                    compatibility = compatibility.Combine(PackageCompatibility.Likely);
                }
            }

            return(compatibility);
        }
Exemple #18
0
 public void UninstallPackage(LocalPackage package)
 {
     this.uninstallQueue.Add(package);
     this.manager.UninstallPackage(package.Id, new SemanticVersion(package.Version), false, true);
     this.uninstallQueue.Clear();
 }