diff --git a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
index a6375d27b5..3de42e8888 100644
--- a/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
+++ b/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs
@@ -581,7 +581,7 @@ Output is package name | current version | available version | pinned?
var output = config.RegularOutput;
config.RegularOutput = false;
- var oudatedPackages = _nugetService.upgrade_noop(config, null);
+ var oudatedPackages = _nugetService.get_outdated(config);
config.RegularOutput = output;
if (config.RegularOutput)
diff --git a/src/chocolatey/infrastructure.app/services/INugetService.cs b/src/chocolatey/infrastructure.app/services/INugetService.cs
index af3c7cf29e..73a589eeef 100644
--- a/src/chocolatey/infrastructure.app/services/INugetService.cs
+++ b/src/chocolatey/infrastructure.app/services/INugetService.cs
@@ -1,13 +1,13 @@
// Copyright © 2017 Chocolatey Software, Inc
// Copyright © 2011 - 2017 RealDimensions Software, LLC
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
-//
+//
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,6 +16,8 @@
namespace chocolatey.infrastructure.app.services
{
+ using System.Collections.Concurrent;
+ using chocolatey.infrastructure.results;
using configuration;
public interface INugetService : ISourceRunner
@@ -49,5 +51,11 @@ public interface INugetService : ISourceRunner
///
/// Name of the package.
void remove_rollback_directory_if_exists(string packageName);
+
+ ///
+ /// Get outdated packages
+ ///
+ /// The configuration.
+ ConcurrentDictionary get_outdated(ChocolateyConfiguration config);
}
}
diff --git a/src/chocolatey/infrastructure.app/services/NugetService.cs b/src/chocolatey/infrastructure.app/services/NugetService.cs
index c937ea8644..6c474934f4 100644
--- a/src/chocolatey/infrastructure.app/services/NugetService.cs
+++ b/src/chocolatey/infrastructure.app/services/NugetService.cs
@@ -1,13 +1,13 @@
// Copyright © 2017 Chocolatey Software, Inc
// Copyright © 2011 - 2017 RealDimensions Software, LLC
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
-//
+//
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -413,7 +413,7 @@ public ConcurrentDictionary install_run(ChocolateyConfigu
}
}
- // this is when someone points the source directly at a nupkg
+ // this is when someone points the source directly at a nupkg
// e.g. -source c:\somelocation\somewhere\packagename.nupkg
if (config.Sources.to_string().EndsWith(Constants.PackageExtension))
{
@@ -668,7 +668,7 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu
if (availablePackage == null)
{
if (config.Features.IgnoreUnfoundPackagesOnUpgradeOutdated) continue;
-
+
string logMessage = "{0} was not found with the source(s) listed.{1} If you specified a particular version and are receiving this message, it is possible that the package name exists but the version does not.{1} Version: \"{2}\"; Source(s): \"{3}\"".format_with(packageName, Environment.NewLine, config.Version, config.Sources);
var unfoundResult = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, version.to_string(), null));
@@ -845,6 +845,109 @@ public ConcurrentDictionary upgrade_run(ChocolateyConfigu
return packageInstalls;
}
+ public ConcurrentDictionary get_outdated(ChocolateyConfiguration config)
+ {
+ var packageManager = NugetCommon.GetPackageManager(
+ config,
+ _nugetLogger,
+ _packageDownloader,
+ installSuccessAction: null,
+ uninstallSuccessAction: null,
+ addUninstallHandler: false);
+
+ var repository = packageManager.SourceRepository;
+ bool isRemote = repository_is_remote(repository);
+
+ var outdatedPackages = new ConcurrentDictionary();
+
+ set_package_names_if_all_is_specified(config, () => { config.IgnoreDependencies = true; });
+ var packageNames = config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null();
+
+ foreach (var packageName in packageNames)
+ {
+ var installedPackage = packageManager.LocalRepository.FindPackage(packageName);
+
+ var pkgInfo = _packageInfoService.get_package_information(installedPackage);
+ bool isPinned = pkgInfo.IsPinned;
+
+ if (config.OutdatedCommand.IgnorePinned && isPinned)
+ {
+ string pinnedLogMessage = "{0} is pinned. Skipping pinned package.".format_with(packageName);
+ var pinnedPackageResult = outdatedPackages.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id)));
+ pinnedPackageResult.Messages.Add(new ResultMessage(ResultType.Debug, pinnedLogMessage));
+ pinnedPackageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, pinnedLogMessage));
+
+ continue;
+ }
+
+ IQueryable results = repository.GetPackages().Where(x => x.Id == packageName);
+
+ var isPrerelease = !string.IsNullOrWhiteSpace(installedPackage.Version.SpecialVersion);
+
+ if (isPrerelease && repository.SupportsPrereleasePackages)
+ {
+ results = results.Where(p => p.IsAbsoluteLatestVersion);
+ }
+ else
+ {
+ results = results.Where(p => p.IsLatestVersion);
+ }
+
+ if (!isRemote)
+ {
+ results = results
+ .Where(PackageExtensions.IsListed)
+ .Where(p => isPrerelease || p.IsReleaseVersion())
+ .AsQueryable();
+ }
+
+ var latestPackage = results.ToList().OrderByDescending(x => x.Version).FirstOrDefault();
+
+ if (latestPackage == null)
+ {
+ if (config.Features.IgnoreUnfoundPackagesOnUpgradeOutdated) continue;
+
+ string unfoundLogMessage = "{0} was not found with the source(s) listed.{1} Source(s): \"{2}\"".format_with(packageName, Environment.NewLine, config.Sources);
+ var unfoundResult = outdatedPackages.GetOrAdd(packageName, new PackageResult(installedPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, installedPackage.Id)));
+ unfoundResult.Messages.Add(new ResultMessage(ResultType.Warn, unfoundLogMessage));
+ unfoundResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, unfoundLogMessage));
+
+ this.Log().Warn("{0}|{1}|{1}|{2}".format_with(installedPackage.Id, installedPackage.Version, isPinned.to_string().to_lower()));
+ continue;
+ }
+
+ if (latestPackage.Version > installedPackage.Version)
+ {
+ var packageResult = outdatedPackages.GetOrAdd(packageName, new PackageResult(latestPackage, _fileSystem.combine_paths(ApplicationParameters.PackagesLocation, latestPackage.Id)));
+
+ string logMessage = "You have {0} v{1} installed. Version {2} is available based on your source(s).{3} Source(s): \"{4}\""
+ .format_with(installedPackage.Id, installedPackage.Version, latestPackage.Version, Environment.NewLine, config.Sources);
+
+ packageResult.Messages.Add(new ResultMessage(ResultType.Note, logMessage));
+
+ this.Log().Info("{0}|{1}|{2}|{3}".format_with(installedPackage.Id, installedPackage.Version, latestPackage.Version, isPinned.to_string().to_lower()));
+ }
+ }
+
+ return outdatedPackages;
+ }
+
+ private bool repository_is_remote(IPackageRepository repository)
+ {
+ bool isRemote;
+ var aggregateRepo = repository as AggregateRepository;
+ if (aggregateRepo != null)
+ {
+ isRemote = aggregateRepo.Repositories.All(repo => repo is IServiceBasedRepository);
+ }
+ else
+ {
+ isRemote = repository is IServiceBasedRepository;
+ }
+
+ return isRemote;
+ }
+
///
/// Sets the configuration for the package upgrade
///
@@ -1034,10 +1137,10 @@ public void backup_changed_files(string packageInstallPath, ChocolateyConfigurat
///
/// Remove the shimgen director files from the package.
- /// These are .gui/.ignore files that may have been created during the installation
+ /// These are .gui/.ignore files that may have been created during the installation
/// process and won't be pulled by the nuget package replacement.
- /// This usually happens when package maintainers haven't been very good about how
- /// they create the files in the past (not using force with new-item typically throws
+ /// This usually happens when package maintainers haven't been very good about how
+ /// they create the files in the past (not using force with new-item typically throws
/// an error if the file exists).
///
/// The configuration.
@@ -1072,10 +1175,10 @@ private void remove_cache_for_package(ChocolateyConfiguration config, IPackage i
}
///
- /// Remove NuGet cache of the package.
+ /// Remove NuGet cache of the package.
/// Whether we use the cached file or not, NuGet always caches the package.
- /// This is annoying with choco, but if you use both choco and NuGet, it can
- /// cause hard to detect issues in NuGet when there is a NuGet package of the
+ /// This is annoying with choco, but if you use both choco and NuGet, it can
+ /// cause hard to detect issues in NuGet when there is a NuGet package of the
/// same name with different contents.
///
/// The installed package.
@@ -1168,12 +1271,12 @@ public ConcurrentDictionary uninstall_run(ChocolateyConfi
}
};
- // if we are uninstalling a package and not forcing dependencies,
+ // if we are uninstalling a package and not forcing dependencies,
// look to see if the user is missing the actual package they meant
// to uninstall.
if (!config.ForceDependencies)
{
- // if you find an install of an .install / .portable / .commandline, allow adding it to the list
+ // if you find an install of an .install / .portable / .commandline, allow adding it to the list
var installedPackages = get_all_installed_packages(config).Select(p => p.Name).ToList().@join(ApplicationParameters.PackageNamesSeparator);
foreach (var packageName in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).or_empty_list_if_null())
{