protected override int LockedExecute(CancellationToken cancellationToken) { repositories.AddRange(Repository == null ? PackageManagerSettings.Current.Repositories.Where(p => p.IsEnabled).Select(s => s.Manager) : Repository.Select(PackageRepositoryHelpers.DetermineRepositoryType)); if (Target == null) { Target = FileSystemHelper.GetCurrentInstallationDirectory(); } versionSpec = VersionSpecifier.Any; if (!String.IsNullOrWhiteSpace(Version)) { versionSpec = VersionSpecifier.Parse(Version); } var targetInstallation = new Installation(Target); try { PackageDef package = GetPackageDef(targetInstallation); if (package == null) { throw new Exception( $"Package {Name} version {Version} not found in specified repositories or local install."); } var ct = new CancellationTokenSource(); var packageVersions = Offline ? new List <PackageVersion>() : repositories.SelectMany(repo => repo.GetPackageVersions(package.Name, ct.Token, null)) .Where(p => versionSpec.IsCompatible(p.Version)); // Remove prereleases if found package is a release if (string.IsNullOrWhiteSpace(package.Version.PreRelease)) { packageVersions = packageVersions.Where(p => string.IsNullOrWhiteSpace(p.Version.PreRelease)); } GetPackageInfo(package, packageVersions.ToList(), targetInstallation); } catch (Exception e) { log.Error(e.Message); return(1); } return(0); }
protected override int LockedExecute(CancellationToken cancellationToken) { if (OS == null) { switch (Environment.OSVersion.Platform) { case PlatformID.MacOSX: OS = "OSX"; break; case PlatformID.Unix: OS = "Linux"; break; default: OS = "Windows"; break; } } List <IPackageRepository> repositories = new List <IPackageRepository>(); if (Installed == false) { if (Repository == null) { repositories.AddRange(PackageManagerSettings.Current.Repositories.Where(p => p.IsEnabled).Select(s => s.Manager)); } else { repositories.AddRange(Repository.Select(s => PackageRepositoryHelpers.DetermineRepositoryType(s))); } } if (Target == null) { Target = FileSystemHelper.GetCurrentInstallationDirectory(); } HashSet <PackageDef> installed = new Installation(Target).GetPackages().ToHashSet(); VersionSpecifier versionSpec = VersionSpecifier.Parse("^"); if (!String.IsNullOrWhiteSpace(Version)) { versionSpec = VersionSpecifier.Parse(Version); } if (string.IsNullOrEmpty(Name)) { var packages = installed.ToList(); packages.AddRange(PackageRepositoryHelpers.GetPackageNameAndVersionFromAllRepos(repositories, new PackageSpecifier("", versionSpec, Architecture, OS))); if (Installed) { packages = packages.Where(p => installed.Any(i => i.Name == p.Name)).ToList(); } PrintReadable(packages, installed); } else { IPackageIdentifier package = installed.FirstOrDefault(p => p.Name == Name); if (Installed) { if (package is null) { log.Info($"{Name} is not installed"); return(-1); } log.Info(package.Version.ToString()); return(0); } List <PackageVersion> versions = null; if (All) { versions = PackageRepositoryHelpers.GetAllVersionsFromAllRepos(repositories, Name).Distinct().ToList(); var versionsCount = versions.Count; if (versionsCount == 0) // No versions { log.Info($"No versions of '{Name}'."); return(0); } if (Version != null) // Version is specified by user { versions = versions.Where(v => versionSpec.IsCompatible(v.Version)).ToList(); } if (versions.Any() == false && versionsCount > 0) { log.Info($"Package '{Name}' does not exists with version '{Version}'."); log.Info($"Package '{Name}' exists in {versionsCount} other versions, please specify a different version."); return(0); } } else { var opentap = new Installation(Target).GetOpenTapPackage(); versions = PackageRepositoryHelpers.GetAllVersionsFromAllRepos(repositories, Name, opentap).Distinct().ToList(); versions = versions.Where(s => s.IsPlatformCompatible(Architecture, OS)).ToList(); if (versions.Any() == false) // No compatible versions { versions = PackageRepositoryHelpers.GetAllVersionsFromAllRepos(repositories, Name).ToList(); if (versions.Any()) { log.Warning($"There are no compatible versions of '{Name}'."); log.Info($"There are {versions.Count} incompatible versions available. Use '--all' to show these."); } else { log.Warning($"Package '{Name}' could not be found in any repository."); } return(0); } versions = versions.Where(v => versionSpec.IsCompatible(v.Version)).ToList(); if (versions.Any() == false) // No versions that are compatible { if (string.IsNullOrEmpty(Version)) { log.Warning($"There are no released versions of '{Name}'."); } else { log.Warning($"Package '{Name}' does not exists with version '{Version}'."); } var anyPrereleaseSpecifier = new VersionSpecifier(versionSpec.Major, versionSpec.Minor, versionSpec.Patch, versionSpec.PreRelease, versionSpec.BuildMetadata, VersionMatchBehavior.AnyPrerelease | versionSpec.MatchBehavior); versions = versions.Where(v => anyPrereleaseSpecifier.IsCompatible(v.Version)).ToList(); if (versions.Any()) { log.Info($"There are {versions.Count} pre-released versions available. Use '--version <pre-release>' (e.g. '--version rc') or '--all' to show these."); } return(0); } } PrintVersionsReadable(package, versions); } return(0); }
internal static List <PackageDef> GatherPackagesAndDependencyDefs(Installation installation, PackageSpecifier[] pkgRefs, string[] packageNames, string Version, CpuArchitecture arch, string OS, List <IPackageRepository> repositories, bool force, bool includeDependencies, bool askToIncludeDependencies, bool noDowngrade) { List <PackageDef> gatheredPackages = new List <PackageDef>(); List <PackageSpecifier> packages = new List <PackageSpecifier>(); if (pkgRefs != null) { packages = pkgRefs.ToList(); } else { if (packageNames == null) { throw new Exception("No packages specified."); } foreach (string packageName in packageNames) { var version = Version; if (Path.GetExtension(packageName).ToLower().EndsWith("tappackages")) { var tempDir = Path.GetTempPath(); var bundleFiles = PluginInstaller.UnpackPackage(packageName, tempDir); var packagesInBundle = bundleFiles.Select(PackageDef.FromPackage); // A packages file may contain the several variants of the same package, try to select one based on OS and Architecture foreach (IGrouping <string, PackageDef> grp in packagesInBundle.GroupBy(p => p.Name)) { var selected = grp.ToList(); if (selected.Count == 1) { gatheredPackages.Add(selected.First()); continue; } if (!string.IsNullOrEmpty(OS)) { selected = selected.Where(p => p.OS.ToLower().Split(',').Any(OS.ToLower().Contains)).ToList(); if (selected.Count == 1) { gatheredPackages.Add(selected.First()); log.Debug("TapPackages file contains packages for several operating systems. Picking only the one for {0}.", OS); continue; } } if (arch != CpuArchitecture.Unspecified) { selected = selected.Where(p => ArchitectureHelper.CompatibleWith(arch, p.Architecture)).ToList(); if (selected.Count == 1) { gatheredPackages.Add(selected.First()); log.Debug("TapPackages file contains packages for several CPU architectures. Picking only the one for {0}.", arch); continue; } } throw new Exception("TapPackages file contains multiple variants of the same package. Unable to autoselect a suitable one."); } } else if (string.IsNullOrWhiteSpace(packageName) == false) { packages.Add(new PackageSpecifier(packageName, VersionSpecifier.Parse(version ?? ""), arch, OS)); } } } foreach (var packageReference in packages) { var installedPackages = installation.GetPackages(); Stopwatch timer = Stopwatch.StartNew(); if (File.Exists(packageReference.Name)) { var package = PackageDef.FromPackage(packageReference.Name); if (noDowngrade) { var installedPackage = installedPackages.FirstOrDefault(p => p.Name == package.Name); if (installedPackage != null && installedPackage.Version.CompareTo(package.Version) >= 0) { log.Info($"The same or a newer version of package '{package.Name}' in already installed."); continue; } } gatheredPackages.Add(package); log.Debug(timer, "Found package {0} locally.", packageReference.Name); } else { PackageDef package = PackageActionHelpers.FindPackage(packageReference, force, installation, repositories); if (noDowngrade) { var installedPackage = installedPackages.FirstOrDefault(p => p.Name == package.Name); if (installedPackage != null && installedPackage.Version.CompareTo(package.Version) >= 0) { log.Info($"The same or a newer version of package '{package.Name}' in already installed."); continue; } } if (PackageCacheHelper.PackageIsFromCache(package)) { log.Debug(timer, "Found package {0} version {1} in local cache", package.Name, package.Version); } else { log.Debug(timer, "Found package {0} version {1}", package.Name, package.Version); } gatheredPackages.Add(package); } } if (gatheredPackages.All(p => p.IsBundle())) { // If we are just installing bundles, we can assume that dependencies should also be installed includeDependencies = true; } log.Debug("Resolving dependencies."); var resolver = new DependencyResolver(installation, gatheredPackages, repositories); if (resolver.UnknownDependencies.Any()) { foreach (var dep in resolver.UnknownDependencies) { string message = string.Format("A package dependency named '{0}' with a version compatible with {1} could not be found in any repository.", dep.Name, dep.Version); if (force) { log.Warning(message); log.Warning("Continuing without downloading dependencies. Plugins will likely not work as expected.", dep.Name); } else { log.Error(message); } } if (!force) { log.Info("To download package dependencies despite the conflicts, use the --force option."); return(null); } } else if (resolver.MissingDependencies.Any()) { string dependencyArgsHint = ""; if (!includeDependencies) { dependencyArgsHint = $" (use --dependencies to also get these)"; } if (resolver.MissingDependencies.Count > 1) { log.Info("{0} required dependencies are currently not installed{1}.", resolver.MissingDependencies.Count, dependencyArgsHint); } else { log.Info("A required dependency is currently not installed{0}.", dependencyArgsHint); } if (includeDependencies) { //log.Debug($"Currently set to download dependencies quietly."); foreach (var package in resolver.MissingDependencies) { log.Debug("Adding dependency {0} {1}", package.Name, package.Version); gatheredPackages.Insert(0, package); } } else if (askToIncludeDependencies) { var pkgs = new List <DepRequest>(); foreach (var package in resolver.MissingDependencies) { // Handle each package at a time. DepRequest req = null; pkgs.Add(req = new DepRequest { PackageName = package.Name, message = string.Format("Add dependency {0} {1} ?", package.Name, package.Version), Response = DepResponse.Add }); UserInput.Request(req, true); } foreach (var pkg in resolver.MissingDependencies) { var res = pkgs.FirstOrDefault(r => r.PackageName == pkg.Name); if ((res != null) && res.Response == DepResponse.Add) { gatheredPackages.Insert(0, pkg); } } } } return(gatheredPackages); }
private PackageDef GetPackageDef(Installation targetInstallation) { // Try a number of methods to obtain the PackageDef in order of precedence var packageRef = new PackageSpecifier(Name, VersionSpecifier.Parse(Version ?? ""), Architecture, OS); PackageDef package; // a relative or absolute file path if (File.Exists(Name)) { package = PackageDef.FromPackage(Name); if (package != null) { Offline = true; return(package); } } // a currently installed package package = targetInstallation.GetPackages().FirstOrDefault(p => p.Name == Name && versionSpec.IsCompatible(p.Version)); if (package != null) { return(package); } if (Offline == false) { try { // a release from repositories package = repositories.SelectMany(x => x.GetPackages(packageRef)) .FindMax(p => p.Version); if (package != null) { return(package); } } catch (System.Net.WebException e) { // not connected to the internet log.Error(e.Message); log.Warning("Could not connect to repository. Showing results for local install"); DisableHttpRepositories(); package = repositories.SelectMany(x => x.GetPackages(packageRef)) .FindMax(p => p.Version); if (package != null) { return(package); } } } if (!string.IsNullOrWhiteSpace(Version)) { log.Warning($"{Name} version {Version} not found."); } if (Offline == false && string.IsNullOrWhiteSpace(Version)) { // a prerelease from repositories packageRef = new PackageSpecifier(Name, VersionSpecifier.Parse("any"), Architecture, OS); package = repositories.SelectMany(x => x.GetPackages(packageRef)) .FindMax(p => p.Version); } return(package); }