public async Task<IEnumerable<V2FeedPackage>> GetPackages(bool logOutput = false)
{
if (logOutput)
{
_mainWindowVm.OutputBuffer.Clear();
isProcessing = true;
}
if(logOutput)
WriteOutput("Checking cache for packages...");
// Ensure that we only retrieve the packages once to refresh the Cache.
await _ss.WaitAsync(200);
var packages = (List<V2FeedPackage>) this._cache.Get(LocalCacheKeyName);
if (packages != null)
{
if(logOutput)
WriteOutput("Found cached packages");
_ss.Release();
return packages;
}
if(logOutput)
WriteOutput("Retrieving local package list.");
var packageResults = await RunPackageCommand("chocolatey list -lo", refreshPackages: false, logOutput: false, clearBuffer: false);
var packageNames = packageResults != null
? packageResults.Select(obj => obj.ToString())
: new List<string>();
var packageDescriptions =
packageNames.Select(packageName => packageName.Split(' '))
.Where(packageArray => packageArray.Count() == 2)
.Select(packageArray => new {
Id = packageArray[0],
Version = packageArray[1]
}).ToList();
if(logOutput)
WriteOutput("Found " + packageDescriptions.Count() + " local packges.");
packages = new List<V2FeedPackage>();
foreach (var packageDesc in packageDescriptions)
{
// ReSharper disable once ReplaceWithSingleCallToSingleOrDefault
// Should we replace this with lazy loading of some sort and move the details retrieval to the PackageViewModel?
// Having LocalChocoService coupled with RemoteService seems like all kinds of bad idea, especially if and when we introduce multiple remote sources.
// Remote sources cause an issue because
// A) If a package is not in the current remote, obviously the remote is unhappy.
// The if(package == null) here _service.IgnoreResourceNotFoundException = true in RemoteChocoService are because of this.
// B) If a package is in two remotes with identical Ids and Versions, you run into potential conflicts.
// This may not be an issue if the package maintainers are uploading the same nupkg to each remote.
var package =
this._remoteService.Packages.Where(
pckge =>
packageDesc.Id == pckge.Id && packageDesc.Version == pckge.Version)
.SingleOrDefault();
if (package == null)
continue;
packages.Add(package);
}
if (logOutput)
WriteOutput("Caching packages.");
this._cache.Set(LocalCacheKeyName, packages, new CacheItemPolicy {
SlidingExpiration = TimeSpan.FromDays(1)
});
if (logOutput)
{
WriteOutput("Done.");
(new Action(() => isProcessing = false)).DelayedExecution(TimeSpan.FromMilliseconds(500));
}
_ss.Release();
NotifyPropertyChanged("Packages");
return packages;
}