public static IEnumerable<Package> SupercedentPackages(this IEnumerable<Package> packageSet, Package package)
        {
            // DebugMessage.Invoke.WriteLine(string.Format( "Scanning for package [{0}]", package.Name.SingleItemAsEnumerable()));
            // anything superceedent in the list of known packages?
            Registrar.ScanForPackages(package);

            return packageSet.Where(p => p.Architecture == package.Architecture &&
                p.PublicKeyToken == package.PublicKeyToken &&
                p.Name.Equals(package.Name, StringComparison.CurrentCultureIgnoreCase) &&
                p.PolicyMinimumVersion <= package.Version &&
                p.PolicyMaximumVersion >= package.Version).OrderByDescending(p => p.Version);
        }
Beispiel #2
0
        private bool CanSatisfyPackage(Package packageToSatisfy, List<Package> installQueue, List<Package> downloadQueue)
        {
            packageToSatisfy.CanSatisfy = false;

            if (packageToSatisfy.IsInstalled) {
                return packageToSatisfy.CanSatisfy = true;
            }

            if (!packageToSatisfy.DoNotSupercede) {
                var supercedents = Registrar.InstalledPackages.SupercedentPackages(packageToSatisfy);
                if (supercedents.Count() > 0) {
                    return true; // a supercedent package is already installed.
                }
            }

            if (!packageToSatisfy.DoNotSupercede) {
                // if told not to supercede, we won't even perform this check
                packageToSatisfy.Supercedent = null;
                var supercedents = Registrar.Packages.SupercedentPackages(packageToSatisfy);

                if (supercedents.Count() > 0) {
                    if (packageToSatisfy.AllowedToSupercede) {
                        foreach (var supercedent in supercedents) {
                            if (CanSatisfyPackage(supercedent, installQueue, downloadQueue)) {
                                packageToSatisfy.Supercedent = supercedent;
                                break;
                            }
                        }
                        // if we have a supercedent, then this package's dependents are moot.)
                        if (packageToSatisfy.Supercedent != null) {
                            return packageToSatisfy.CanSatisfy = true;
                        }
                    }
                    else {
                        // the user hasn't specifically asked us to supercede, yet we know of
                        // potential supercedents. Let's force the user to make a decision.
                        // throw new PackageHasPotentialUpgradesException(packageToSatisfy, supercedents);
                        PackageManagerMessages.Invoke.PackageHasPotentialUpgrades(packageToSatisfy, supercedents);
                        throw new OperationCompletedBeforeResultException();
                    }
                }
            }

            if (packageToSatisfy.CouldNotDownload || packageToSatisfy.PackageFailedInstall) {
                return false;
            }

            foreach (var dependentPackage in packageToSatisfy.Dependencies) {
                if (!CanSatisfyPackage(dependentPackage, installQueue, downloadQueue)) {
                    return false;
                }
            }

            if (!packageToSatisfy.HasLocalFile) {
                if (downloadQueue != null) {
                    downloadQueue.Add(packageToSatisfy);
                }
            }
            else {
                if (installQueue != null) {
                    installQueue.Add(packageToSatisfy);
                }
            }

            return packageToSatisfy.CanSatisfy = true;
        }
        /// <summary>
        /// This generates a list of files that need to be installed to sastisy a given package.
        /// </summary>
        /// <param name="package"></param>
        /// <returns></returns>
        private IEnumerable<Package> GenerateInstallGraph(Package package, bool hypothetical = false)
        {
            if (package.IsInstalled) {
                if (!package.PackageRequestData.NotifiedClientThisSupercedes) {
                    PackageManagerMessages.Invoke.PackageSatisfiedBy(package, package);
                    package.PackageRequestData.NotifiedClientThisSupercedes = true;
                }

                yield break;
            }

            var packageData = package.PackageSessionData;

            if (!package.PackageSessionData.IsPotentiallyInstallable) {
                yield break;
            }

            if (!packageData.DoNotSupercede) {
                var installedSupercedents = SearchForInstalledPackages(package.Name, null, package.Architecture, package.PublicKeyToken);

                if( package.PackageSessionData.IsClientSpecified || hypothetical )  {
                    // this means that we're talking about a requested package
                    // and not a dependent package and we can liberally construe supercedent
                    // as anything with a highger version number
                    installedSupercedents =  (from p in installedSupercedents where p.Version > package.Version select p).OrderByDescending(p => p.Version).ToArray();

                } else {
                    // otherwise, we're installing a dependency, and we need something compatable.
                    installedSupercedents =  (from p in installedSupercedents
                                where p.InternalPackageData.PolicyMinimumVersion <= package.Version &&
                                      p.InternalPackageData.PolicyMaximumVersion >= package.Version select p).OrderByDescending(p => p.Version).ToArray();
                }
                var installedSupercedent = installedSupercedents.FirstOrDefault();
                if (installedSupercedent != null ) {
                    if (!installedSupercedent.PackageRequestData.NotifiedClientThisSupercedes) {
                        PackageManagerMessages.Invoke.PackageSatisfiedBy(package, installedSupercedent);
                        installedSupercedent.PackageRequestData.NotifiedClientThisSupercedes = true;
                    }
                    yield break; // a supercedent package is already installed.
                }

                // if told not to supercede, we won't even perform this check
                packageData.Supercedent = null;

                var supercedents = SearchForPackages(package.Name, null, package.Architecture, package.PublicKeyToken).ToArray();

                if( package.PackageSessionData.IsClientSpecified || hypothetical )  {
                    // this means that we're talking about a requested package
                    // and not a dependent package and we can liberally construe supercedent
                    // as anything with a highger version number
                    supercedents =  (from p in supercedents where p.Version > package.Version select p).OrderByDescending(p => p.Version).ToArray();

                } else {
                    // otherwise, we're installing a dependency, and we need something compatable.
                    supercedents =  (from p in supercedents
                                where p.InternalPackageData.PolicyMinimumVersion <= package.Version &&
                                      p.InternalPackageData.PolicyMaximumVersion >= package.Version select p).OrderByDescending(p => p.Version).ToArray();
                }

                if (supercedents.Any()) {
                    if (packageData.AllowedToSupercede) {
                        foreach (var supercedent in supercedents) {
                            IEnumerable<Package> children;
                            try {
                                children = GenerateInstallGraph(supercedent, true);
                            }
                            catch {
                                // can't be satisfied with that supercedent.
                                // we can quietly move along here.
                                continue;
                            }

                            // we should tell the client that we're making a substitution.
                            if (!supercedent.PackageRequestData.NotifiedClientThisSupercedes) {
                                PackageManagerMessages.Invoke.PackageSatisfiedBy(package, supercedent);
                                supercedent.PackageRequestData.NotifiedClientThisSupercedes = true;
                            }

                            if( supercedent.Name == package.Name ) {
                                supercedent.PackageSessionData.IsClientSpecified = package.PackageSessionData.IsClientSpecified;
                            }

                            // since we got to this spot, we can assume that we can
                            // supercede this package with the results of the successful
                            // GIG call.
                            foreach (var child in children) {
                                yield return child;
                            }

                            // if we have a supercedent, then this package's dependents are moot.)
                            yield break;
                        }
                    }
                    else {
                        // the user hasn't specifically asked us to supercede, yet we know of
                        // potential supercedents. Let's force the user to make a decision.
                        // throw new PackageHasPotentialUpgradesException(packageToSatisfy, supercedents);
                        PackageManagerMessages.Invoke.PackageHasPotentialUpgrades(package, supercedents);
                        throw new OperationCompletedBeforeResultException();
                    }
                }
            }

            if (packageData.CouldNotDownload) {
                if (!hypothetical) {
                    PackageManagerMessages.Invoke.UnableToDownloadPackage(package);
                }
                throw new OperationCompletedBeforeResultException();
            }

            if (packageData.PackageFailedInstall) {
                if (!hypothetical) {
                    PackageManagerMessages.Invoke.UnableToInstallPackage(package);
                }
                throw new OperationCompletedBeforeResultException();
            }

            var childrenFailed = false;
            foreach( var d in package.InternalPackageData.Dependencies ) {
                IEnumerable<Package> children;
                try {
                    children = GenerateInstallGraph(d);
                }
                catch {
                    childrenFailed = true;
                    continue;
                }

                foreach (var child in children)
                    yield return child;
            }

            if(childrenFailed) {
                throw new OperationCompletedBeforeResultException();
            }

            yield return package;
        }
Beispiel #4
0
 private static void AddPackage( Package package)
 {
     lock( _packages ) {
         _packages.Add(package);
     }
 }
Beispiel #5
0
 internal static IEnumerable<Package> ScanForPackages(Package package)
 {
     var feeds = _autoFeedLocations.Union(_sessionFeedLocations).Union(_systemFeedLocations);
     feeds = DoNotScanLocations.Aggregate(feeds,
         (current, loc) => (from feed in current where !feed.Location.IsWildcardMatch(loc) select feed));
     return feeds.Aggregate(Enumerable.Empty<Package>(), (current, feed) => current.Union(feed.FindPackages(package)));
 }
Beispiel #6
0
        internal static Package GetPackage(string packagePath)
        {
            Package pkg;
            Guid pkgGuid;

            if (packagePath.Contains("*")) {
                throw new PackageNotFoundException(packagePath);
            }

            // supports looking up by productcode/packageID.
            if( packagePath[0] == '{' && Guid.TryParse(packagePath, out pkgGuid)) {
                pkg = _packages.Where(package => package.ProductCode == packagePath).FirstOrDefault();
                if( pkg == null ) {
                    // where the only thing we know is packageID.
                    pkg = new Package(packagePath);
                    AddPackage(pkg);
                }
                return pkg;
            }

            // lookup by canonical name.
            var match = _canonicalFilter.Match(packagePath);
            if( match.Success ) {
                return GetPackage(match.Groups[1].Value, match.Groups[2].Value.VersionStringToUInt64(), match.Groups[3].Value, match.Groups[4].Value,
                    string.Empty);
            }

            // assuming at this point, it should be a filename?
            var localPackagePath = Path.GetFullPath(packagePath);

            if (!File.Exists(localPackagePath)) {
                // could this be another representation of a package?
                // not sure we ever ever get here anymore.

                if (!localPackagePath.EndsWith(".msi")) {
                    Console.WriteLine("Trying package name with .msi appendend. Is this used?");
                    return GetPackage(localPackagePath + ".msi");
                }

                throw new PackageNotFoundException(localPackagePath);
            }

            var lookup = File.GetCreationTime(localPackagePath).Ticks + localPackagePath.GetHashCode();

            if (_nonCoAppMSIFiles.Contains(lookup)) {
                throw new InvalidPackageException(InvalidReason.NotCoAppMSI, localPackagePath);
            }

            lock (_packages) {
                pkg = (_packages.Where(
                    package =>
                        package.HasLocalFile && package.LocalPackagePath.ContainsValue(localPackagePath))).
                    FirstOrDefault();
            }
            if (pkg != null) {
                return pkg;
            }

            var localFolder = Path.GetDirectoryName(localPackagePath).ToLower();
            // remember this place for finding packages
            AddAutoFeedLocation(localFolder);

            try {
                var pkgDetails = CoAppMSI.GetCoAppPackageFileDetails(localPackagePath);

                // try via just the package id
                if (!string.IsNullOrEmpty(pkgDetails.packageId)) {
                    lock (_packages) {
                        pkg = _packages.Where(package => package.ProductCode == pkgDetails.packageId).FirstOrDefault();
                    }
                }

                // try via the cosmetic name fields
                if (pkg == null) {
                    lock (_packages) {
                        pkg = (_packages.Where(package =>
                            package.Architecture == pkgDetails.Architecture &&
                                package.Version == pkgDetails.Version &&
                                    package.PublicKeyToken == pkgDetails.PublicKeyToken &&
                                        package.Name.Equals(pkgDetails.Name, StringComparison.CurrentCultureIgnoreCase))).FirstOrDefault();
                    }
                }

                if (pkg == null) {
                    pkg = new Package(pkgDetails.Name, pkgDetails.Architecture, pkgDetails.Version, pkgDetails.PublicKeyToken,
                        pkgDetails.packageId);

                    AddPackage(pkg);
                }

                if (string.IsNullOrEmpty(pkg.ProductCode)) {
                    pkg.ProductCode = pkgDetails.packageId;
                }

                if (pkg.Dependencies.Count == 0) {
                    pkg.Dependencies.AddRange((IEnumerable<Package>) pkgDetails.dependencies);
                }

                pkg.LocalPackagePath.Value = localPackagePath;

                pkg.Assemblies.AddRange((IEnumerable<PackageAssemblyInfo>) pkgDetails.assemblies.Values);
                pkg.Roles.AddRange((IEnumerable<Tuple<PackageRole, string>>) pkgDetails.roles);

                pkg.PolicyMinimumVersion = pkgDetails.policy_min_version;
                pkg.PolicyMaximumVersion = pkgDetails.policy_max_version;

                // pkgDetails.displayName
                pkg.FullDescription = pkgDetails.description;
                pkg.PublishDate = DateTime.Parse(pkgDetails.publishDate);
                pkg.AuthorVersion = pkgDetails.authorVersion;
                pkg.CanonicalPackageLocation = pkgDetails.originalLocation;
                pkg.CanonicalFeedLocation = pkgDetails.feedLocation;
                pkg.Base64IconData = pkgDetails.icon;
                pkg.SummaryDescription = pkgDetails.summary;
                pkg.Publisher.Name = pkgDetails.publisherName;
                pkg.Publisher.Url = pkgDetails.publisherUrl;
                pkg.Publisher.Email = pkgDetails.publisherEmail;

                pkg.packageHandler = new CoAppMSI();

                return pkg;
            }
            catch (InvalidPackageException ipe) {
                if (ipe.Reason == InvalidReason.NotCoAppMSI) {
                    _nonCoAppMSIFiles.Add(lookup);
                }
                throw;
            }
        }
Beispiel #7
0
        internal static Package GetPackage(string packageName, UInt64 version,string architecture, string publicKeyToken, string packageId)
        {
            Package pkg;

            // try via just the package id
            if (!string.IsNullOrEmpty(packageId)) {
                lock (_packages) {
                    pkg = _packages.Where(package => package.ProductCode == packageId).FirstOrDefault();
                }

                if (pkg != null && string.IsNullOrEmpty(pkg.Name)) {
                    pkg.SetPackageProperties(packageName, architecture, version, publicKeyToken);
                }
                if (pkg != null)
                    return pkg;
            }

            lock (_packages) {
                pkg = (_packages.Where(package =>
                    package.Architecture == architecture &&
                        package.Version == version &&
                            package.PublicKeyToken == publicKeyToken &&
                                package.Name.Equals(packageName, StringComparison.CurrentCultureIgnoreCase))).FirstOrDefault();
            }

            if (pkg == null) {
                pkg = new Package(packageName, architecture, version, publicKeyToken, packageId);
                AddPackage(pkg);
            }

            if( !string.IsNullOrEmpty(packageId) && string.IsNullOrEmpty(pkg.ProductCode) ) {
                pkg.ProductCode = packageId;
            }

            return pkg;
        }
 internal PackageSessionData(Package package) {
     _package = package;
 }
 internal InternalPackageData(Package package) {
     _package = package;
      Dependencies.CollectionChanged += (x, y) => Changed();
 }
        internal static Package GetPackage(string packageName, ulong version, string architecture, string publicKeyToken, Guid? productCode) {
            Package pkg;

            // try via just the package product code
            if (productCode != null) {
                lock (_packages) {
                    pkg = _packages.Where(package => package.ProductCode == productCode).FirstOrDefault();
                }

                if (pkg != null) {
                    // if we *have* this package somewhere, but don't know its name, 
                    // we can now fill *that* in.
                    if (string.IsNullOrEmpty(pkg.Name)) {
                        pkg.Name = packageName;
                        pkg.Architecture = architecture;
                        pkg.Version = version;
                        pkg.PublicKeyToken = publicKeyToken;
                    }
                       return pkg;
                }
            }

            lock (_packages) {
                pkg = (_packages.Where(package =>
                            package.Architecture == architecture && package.Version == version && package.PublicKeyToken == publicKeyToken &&
                                package.Name.Equals(packageName, StringComparison.CurrentCultureIgnoreCase))).FirstOrDefault();

                // we've tried finding it a couple of ways, and got back nothing for our trouble.
                // we'll create an package with the details we have, and pass that back.
                if (pkg == null) {
                    pkg = new Package(packageName, architecture, version, publicKeyToken, productCode);
                    _packages.Add(pkg);
                }
            }

            // if we did find a package and its product code was empty, we can fill that in now if we have it.
            if (productCode !=null && pkg.ProductCode == null) {
                pkg.ProductCode = productCode;
            }

            return pkg;
        }
 internal static  Package GetPackageFromCanonicalName(string canonicalName) {
     lock (_packages) {
         var packageName = PackageName.Parse(canonicalName);
         if (packageName.IsFullMatch) {
             var pkg = _packages.Where(package => package.CanonicalName == canonicalName).FirstOrDefault();
             if (pkg == null) {
                 // where the only thing we know is canonical Name.
                 pkg = new Package(packageName.Name, packageName.Arch, packageName.Version.VersionStringToUInt64(), packageName.PublicKeyToken, null);
                 _packages.Add(pkg);
             }
             return pkg;
         }
     }
     return null; // only happens if the canonicalName isn't a canonicalName.
 }
 internal static Package GetPackageFromProductCode(Guid? productCode) {
     if (productCode != null ) {
         lock (_packages) {
             var pkg = _packages.Where(package => package.ProductCode == productCode).FirstOrDefault();
             if (pkg == null) {
                 // where the only thing we know is product code.
                 pkg = new Package(productCode);
                 _packages.Add(pkg);
             }
             return pkg;
         }
     }
     return null; // only happens if the productCode isn't a guid.
 }
 internal PackageRequestData(Package package) {
     _package = package;
 }
Beispiel #14
0
 public CompositionRule(Package package)
 {
     _package = package;
 }
Beispiel #15
0
 public bool IsAnUpgradeFor(Package olderPackage) {
     return
         IsSameFamily(olderPackage) &&
         Version > olderPackage.Version && 
         !(InternalPackageData.PolicyMinimumVersion <= olderPackage.Version &&
         InternalPackageData.PolicyMaximumVersion >= olderPackage.Version);
 }
Beispiel #16
0
 public bool IsSameFamily(Package olderPackage) {
     return Name == olderPackage.Name &&
         Architecture == olderPackage.Architecture &&
         PublicKeyToken == olderPackage.PublicKeyToken;
 }