public async Task<PackageSpec> GetInstallablePackageAsync(PackageSpec package, CancellationToken cancellationToken) { if (!package.IsValid) { return new PackageSpec(); } await Task.Delay(10); return _installable.FirstOrDefault(p => p.Name == package.Name) ?? new PackageSpec(); }
public async Task<bool> InstallAsync(PackageSpec package, IPackageManagerUI ui, CancellationToken cancellationToken) { ui?.OnOperationStarted(this, "install " + package.FullSpec); _installed.Add(package); await Task.Delay(100, cancellationToken); _seenChange = true; ui?.OnOperationFinished(this, "install " + package.FullSpec, true); return true; }
public InterpretersPackageNode(PythonProjectNode project, PackageSpec spec) : base(project, new VirtualProjectElement(project)) { ExcludeNodeFromScc = true; _package = spec.Clone(); _packageName = spec.FullSpec; if (spec.ExactVersion.IsEmpty) { _caption = spec.Name; _canUninstall = false; } else { _caption = string.Format("{0} ({1})", spec.Name, spec.ExactVersion); _canUninstall = !CannotUninstall.Contains(spec.Name); } }
public async Task <PackageSpec> GetPackageInfoAsync(PackageSpec entry, CancellationToken cancel) { string description = null; List <string> versions = null; bool useCache = IsInLiveCache(entry.Name); if (useCache) { using (await _cacheLock.LockAsync(cancel)) { PackageSpec result; if (_cache.TryGetValue(entry.Name, out result)) { return(result.Clone()); } else { return(new PackageSpec()); } } } TaskCompletionSource <PackageSpec> tcs = null; Task <PackageSpec> t = null; lock (_activeRequests) { if (_activeRequests.TryGetValue(entry.Name, out tcs)) { t = tcs.Task; } else { _activeRequests[entry.Name] = tcs = new TaskCompletionSource <PackageSpec>(); } } if (t != null) { return((await t).Clone()); } try { using (var client = new WebClient()) { Stream data; client.Headers[HttpRequestHeader.UserAgent] = UserAgent; try { data = await client.OpenReadTaskAsync(new Uri(Index, entry.Name + "/json")) .ConfigureAwait(false); } catch (WebException) { // No net access or no such package AddToLiveCache(entry.Name); return(new PackageSpec()); } try { using (var reader = JsonReaderWriterFactory.CreateJsonReader(data, new XmlDictionaryReaderQuotas())) { var doc = XDocument.Load(reader); // TODO: Get package URL //url = (string)doc.Document // .Elements("root") // .Elements("info") // .Elements("package_url") // .FirstOrDefault(); description = (string)doc.Document .Elements("root") .Elements("info") .Elements("description") .FirstOrDefault(); versions = doc.Document .Elements("root") .Elements("releases") .Elements() .Attributes("item") .Select(a => a.Value) .ToList(); } } catch (InvalidOperationException) { } } bool changed = false; PackageSpec result; using (await _cacheLock.LockAsync(cancel)) { if (!_cache.TryGetValue(entry.Name, out result)) { result = _cache[entry.Name] = new PackageSpec(entry.Name); } if (!string.IsNullOrEmpty(description)) { var lines = description.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); var firstLine = string.Join( " ", lines.TakeWhile(s => !IsSeparatorLine(s)).Select(s => s.Trim()) ); if (firstLine.Length > 500) { firstLine = firstLine.Substring(0, 497) + "..."; } if (firstLine == "UNKNOWN") { firstLine = string.Empty; } result.Description = firstLine; changed = true; } if (versions != null) { var updateVersion = PackageVersion.TryParseAll(versions) .Where(v => v.IsFinalRelease) .OrderByDescending(v => v) .FirstOrDefault(); result.ExactVersion = updateVersion; changed = true; } } if (changed) { TriggerWriteCacheToDisk(); AddToLiveCache(entry.Name); } var r = result.Clone(); // Inform other waiters that we have completed tcs.TrySetResult(r); return(r); } catch (Exception ex) { tcs.TrySetException(ex); throw; } finally { lock (_activeRequests) { _activeRequests.Remove(entry.Name); } } }
public async Task<PackageSpec> GetInstallablePackageAsync(PackageSpec package, CancellationToken cancellationToken) { if (!package.IsValid) { return package; } return await _cache.GetPackageInfoAsync(package, cancellationToken); }
public async Task<PackageSpec> GetInstalledPackageAsync(PackageSpec package, CancellationToken cancellationToken) { if (!package.IsValid) { return package; } using (await _working.LockAsync(cancellationToken)) { if (!_everCached) { await CacheInstalledPackagesAsync(true, false, cancellationToken); } return _packages.FirstOrDefault(p => p.Name == package.Name) ?? new PackageSpec(null); } }
public async Task<bool> UninstallAsync(PackageSpec package, IPackageManagerUI ui, CancellationToken cancellationToken) { AbortOnInvalidConfiguration(); await AbortIfNotReady(cancellationToken); bool success = false; var args = _extraInterpreterArgs.ToList(); if (!SupportsDashMPip) { args.Add("-c"); args.Add("\"import pip; pip.main()\""); } else { args.Add("-m"); args.Add("pip"); } args.Add("uninstall"); args.Add("-y"); args.Add(package.FullSpec); var name = string.IsNullOrEmpty(package.Name) ? package.FullSpec : package.Name; var operation = string.Join(" ", args); try { using (await _working.LockAsync(cancellationToken)) { ui?.OnOperationStarted(this, operation); ui?.OnOutputTextReceived(this, Strings.InstallingPackageStarted.FormatUI(name)); using (var output = ProcessOutput.Run( _factory.Configuration.InterpreterPath, args, _factory.Configuration.PrefixPath, UnbufferedEnv, false, PackageManagerUIRedirector.Get(this, ui), elevate: await ShouldElevate(ui, operation) )) { if (!output.IsStarted) { // The finally block handles output return false; } var exitCode = await output; success = exitCode == 0; } return success; } } catch (IOException) { return false; } finally { if (!success) { // Check whether we failed because pip is missing UpdateIsReadyAsync(false, CancellationToken.None).DoNotWait(); } if (IsReady) { await CacheInstalledPackagesAsync(false, false, cancellationToken); if (!success) { // Double check whether the package has actually // been uninstalled, to avoid reporting errors // where, for all practical purposes, there is no // error. if (!(await GetInstalledPackageAsync(package, cancellationToken)).IsValid) { success = true; } } } var msg = success ? Strings.UninstallingPackageSuccess : Strings.UninstallingPackageFailed; ui?.OnOutputTextReceived(this, msg.FormatUI(name)); ui?.OnOperationFinished(this, operation, success); } }
public async Task <bool> InstallAsync(PackageSpec package, IPackageManagerUI ui, CancellationToken cancellationToken) { AbortOnInvalidConfiguration(); await AbortIfNotReady(cancellationToken); bool success = false; var args = _extraInterpreterArgs.ToList(); if (!SupportsDashMPip) { args.Add("-c"); args.Add("\"import pip; pip.main()\""); } else { args.Add("-m"); args.Add("pip"); } args.Add("install"); args.Add(package.FullSpec); var name = string.IsNullOrEmpty(package.Name) ? package.FullSpec : package.Name; var operation = string.Join(" ", args); using (await _working.LockAsync(cancellationToken)) { ui?.OnOperationStarted(this, operation); ui?.OnOutputTextReceived(this, Strings.InstallingPackageStarted.FormatUI(name)); try { using (var output = ProcessOutput.Run( _factory.Configuration.InterpreterPath, args, _factory.Configuration.PrefixPath, UnbufferedEnv, false, PackageManagerUIRedirector.Get(this, ui), quoteArgs: false, elevate: await ShouldElevate(ui, operation) )) { if (!output.IsStarted) { return(false); } var exitCode = await output; success = exitCode == 0; } return(success); } catch (IOException) { return(false); } finally { if (!success) { // Check whether we failed because pip is missing UpdateIsReadyAsync(true, CancellationToken.None).DoNotWait(); } var msg = success ? Strings.InstallingPackageSuccess : Strings.InstallingPackageFailed; ui?.OnOutputTextReceived(this, msg.FormatUI(name)); ui?.OnOperationFinished(this, operation, success); await CacheInstalledPackagesAsync(true, cancellationToken); } } }
public void AddInstallable(PackageSpec package) { _installable.Add(package); }
public Task<bool> UninstallAsync(PackageSpec package, IPackageManagerUI ui, CancellationToken cancellationToken) { throw new NotSupportedException(); }
public async Task <bool> UninstallAsync(PackageSpec package, IPackageManagerUI ui, CancellationToken cancellationToken) { AbortOnInvalidConfiguration(); await AbortIfNotReady(cancellationToken); bool success = false; var args = new List <string>(); args.Add("uninstall"); args.Add("-p"); args.Add(ProcessOutput.QuoteSingleArgument(_factory.Configuration.GetPrefixPath())); args.Add("-y"); args.Add(package.Name); var name = string.IsNullOrEmpty(package.Name) ? package.FullSpec : package.Name; var operation = string.Join(" ", args); try { using (await _working.LockAsync(cancellationToken)) { ui?.OnOperationStarted(this, operation); ui?.OnOutputTextReceived(this, Strings.UninstallingPackageStarted.FormatUI(name)); using (var output = ProcessOutput.Run( _condaPath, args, _factory.Configuration.GetPrefixPath(), UnbufferedEnv, false, PackageManagerUIRedirector.Get(this, ui), elevate: await ShouldElevate(ui, operation) )) { if (!output.IsStarted) { // The finally block handles output return(false); } var exitCode = await output; success = exitCode == 0; } return(success); } } catch (IOException) { return(false); } finally { if (!success) { // Check whether we failed because conda is missing UpdateIsReadyAsync(false, CancellationToken.None).DoNotWait(); } if (IsReady) { await CacheInstalledPackagesAsync(false, false, cancellationToken); if (!success) { // Double check whether the package has actually // been uninstalled, to avoid reporting errors // where, for all practical purposes, there is no // error. if (!(await GetInstalledPackageAsync(package, cancellationToken)).IsValid) { success = true; } } } var msg = success ? Strings.UninstallingPackageSuccess : Strings.UninstallingPackageFailed; ui?.OnOutputTextReceived(this, msg.FormatUI(name)); ui?.OnOperationFinished(this, operation, success); } }
public Task<PackageSpec> GetInstalledPackageAsync(PackageSpec package, CancellationToken cancellationToken) { if (!package.IsValid) { return Task.FromResult(new PackageSpec()); } return Task.FromResult(_installed.FirstOrDefault(p => p.Name == package.Name) ?? new PackageSpec()); }
private async Task CacheInstalledPackagesAsync( bool alreadyHasLock, bool alreadyHasConcurrencyLock, CancellationToken cancellationToken ) { if (!IsReady) { await UpdateIsReadyAsync(alreadyHasLock, cancellationToken); if (!IsReady) { return; } } List <PackageSpec> packages = null; var workingLock = alreadyHasLock ? null : await _working.LockAsync(cancellationToken); try { var args = _pipListHasFormatOption ? _commands.ListJson() : _commands.List(); var concurrencyLock = alreadyHasConcurrencyLock ? null : await _concurrencyLock.LockAsync(cancellationToken); try { using (var proc = ProcessOutput.Run( _factory.Configuration.InterpreterPath, args, _factory.Configuration.GetPrefixPath(), UnbufferedEnv, false, null )) { try { if ((await proc) == 0) { if (_pipListHasFormatOption) { try { var data = JToken.ReadFrom(new JsonTextReader(new StringListReader(proc.StandardOutputLines))); packages = data .Select(j => new PackageSpec(j.Value <string>("name"), j.Value <string>("version"))) .Where(p => p.IsValid) .OrderBy(p => p.Name) .ToList(); } catch (JsonException ex) { Debug.WriteLine("Failed to parse: {0}".FormatInvariant(ex.Message)); foreach (var l in proc.StandardOutputLines) { Debug.WriteLine(l); } } } else { packages = proc.StandardOutputLines .Select(i => PackageSpec.FromPipList(i)) .Where(p => p.IsValid) .OrderBy(p => p.Name) .ToList(); } } else if (_pipListHasFormatOption) { // Actually, pip probably doesn't have the --format option Debug.WriteLine("{0} does not support --format".FormatInvariant(_factory.Configuration.InterpreterPath)); _pipListHasFormatOption = false; await CacheInstalledPackagesAsync(true, true, cancellationToken); return; } else { } } catch (OperationCanceledException) { // Process failed to run Debug.WriteLine("Failed to run pip to collect packages"); foreach (var line in proc.StandardOutputLines) { Debug.WriteLine(line); } } } if (packages == null) { // Pip failed, so return a directory listing var paths = await PythonLibraryPath.GetDatabaseSearchPathsAsync(_factory.Configuration, null); packages = await Task.Run(() => paths.Where(p => !p.IsStandardLibrary && Directory.Exists(p.Path)) .SelectMany(p => PathUtils.EnumerateDirectories(p.Path, recurse: false)) .Select(path => Path.GetFileName(path)) .Select(name => PackageNameRegex.Match(name)) .Where(match => match.Success) .Select(match => new PackageSpec(match.Groups["name"].Value)) .Where(p => p.IsValid) .OrderBy(p => p.Name) .ToList()); } } finally { concurrencyLock?.Dispose(); } // Outside of concurrency lock, still in working lock _packages.Clear(); _packages.AddRange(packages); _everCached = true; } finally { workingLock?.Dispose(); } InstalledPackagesChanged?.Invoke(this, EventArgs.Empty); _factory.NotifyImportNamesChanged(); }
public bool CanUninstall(PackageSpec package) { return(true); }
public Task <PackageSpec> GetInstalledPackageAsync(PackageSpec package, CancellationToken cancellationToken) { return(Task.FromResult(new PackageSpec())); }
public Task <bool> UninstallAsync(PackageSpec package, IPackageManagerUI ui, CancellationToken cancellationToken) { throw new NotSupportedException(); }
private async Task CacheInstalledPackagesAsync(bool alreadyHasLock, CancellationToken cancellationToken) { if (!IsReady) { await UpdateIsReadyAsync(alreadyHasLock, cancellationToken); if (!IsReady) { return; } } List <PackageSpec> packages = null; var workingLock = alreadyHasLock ? null : await _working.LockAsync(cancellationToken); try { var args = _extraInterpreterArgs.ToList(); if (!SupportsDashMPip) { args.Add("-c"); args.Add("\"import pip; pip.main()\""); } else { args.Add("-m"); args.Add("pip"); } args.Add("list"); using (await _concurrencyLock.LockAsync(cancellationToken)) { using (var proc = ProcessOutput.Run( _factory.Configuration.InterpreterPath, args, _factory.Configuration.PrefixPath, UnbufferedEnv, false, null )) { try { if (await proc == 0) { packages = proc.StandardOutputLines .Select(i => PackageSpec.FromPipList(i)) .Where(p => p.IsValid) .OrderBy(p => p.Name) .ToList(); } } catch (OperationCanceledException) { // Process failed to run Debug.WriteLine("Failed to run pip to collect packages"); Debug.WriteLine(string.Join(Environment.NewLine, proc.StandardOutputLines)); } } if (packages == null) { // Pip failed, so return a directory listing var paths = await PythonTypeDatabase.GetDatabaseSearchPathsAsync(_factory); packages = await Task.Run(() => paths.Where(p => !p.IsStandardLibrary && Directory.Exists(p.Path)) .SelectMany(p => PathUtils.EnumerateDirectories(p.Path, recurse: false)) .Select(path => Path.GetFileName(path)) .Select(name => PackageNameRegex.Match(name)) .Where(match => match.Success) .Select(match => new PackageSpec(match.Groups["name"].Value)) .Where(p => p.IsValid) .OrderBy(p => p.Name) .ToList()); } } // Outside of concurrency lock, still in working lock _packages.Clear(); _packages.AddRange(packages); _everCached = true; } finally { workingLock?.Dispose(); } InstalledPackagesChanged?.Invoke(this, EventArgs.Empty); }
public async Task<PackageSpec> GetPackageInfoAsync(PackageSpec entry, CancellationToken cancel) { string description = null; List<string> versions = null; lock (NotOnPyPI) { if (NotOnPyPI.Contains(entry.Name)) { return new PackageSpec(); } } using (var client = new WebClient()) { Stream data; try { data = await client.OpenReadTaskAsync(new Uri(_index ?? DefaultIndex, entry.Name + "/json")); } catch (WebException ex) { if ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { lock (NotOnPyPI) { NotOnPyPI.Add(entry.Name); } } // No net access or no such package return new PackageSpec(); } try { using (var reader = JsonReaderWriterFactory.CreateJsonReader(data, new XmlDictionaryReaderQuotas())) { var doc = XDocument.Load(reader); // TODO: Get package URL //url = (string)doc.Document // .Elements("root") // .Elements("info") // .Elements("package_url") // .FirstOrDefault(); description = (string)doc.Document .Elements("root") .Elements("info") .Elements("description") .FirstOrDefault(); versions = doc.Document .Elements("root") .Elements("releases") .Elements() .Attributes("item") .Select(a => a.Value) .ToList(); } } catch (InvalidOperationException) { } } bool changed = false; PackageSpec result; using (await _cacheLock.LockAsync(cancel)) { if (!_cache.TryGetValue(entry.Name, out result)) { result = _cache[entry.Name] = new PackageSpec(entry.Name); } if (!string.IsNullOrEmpty(description)) { var lines = description.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); var firstLine = string.Join( " ", lines.TakeWhile(s => !IsSeparatorLine(s)).Select(s => s.Trim()) ); if (firstLine.Length > 500) { firstLine = firstLine.Substring(0, 497) + "..."; } if (firstLine == "UNKNOWN") { firstLine = string.Empty; } result.Description = firstLine; changed = true; } if (versions != null) { var updateVersion = PackageVersion.TryParseAll(versions) .Where(v => v.IsFinalRelease) .OrderByDescending(v => v) .FirstOrDefault(); result.ExactVersion = updateVersion; changed = true; } } if (changed) { TriggerWriteCacheToDisk(); } return result.Clone(); }
private async Task RefreshCacheAsync(CancellationToken cancel) { Debug.Assert(_cacheLock.CurrentCount == 0, "Cache must be locked before calling RefreshCacheAsync"); string htmlList; using (var client = new WebClient()) { // ../simple is a list of <a href="package">package</a> try { htmlList = await client.DownloadStringTaskAsync( new Uri(_index ?? DefaultIndex, "../simple") ).ConfigureAwait(false); } catch (WebException) { // No net access, so can't refresh return; } } bool changed = false; var toRemove = new HashSet<string>(_cache.Keys); // We only want to add new packages so we don't blow away // existing package specs in the cache. foreach (Match match in SimpleListRegex.Matches(htmlList)) { var package = match.Groups["package"].Value; if (string.IsNullOrEmpty(package)) { continue; } if (!toRemove.Remove(package)) { try { _cache[package] = new PackageSpec(package); changed = true; } catch (FormatException) { } } } foreach (var package in toRemove) { _cache.Remove(package); changed = true; } if (changed) { TriggerWriteCacheToDisk(); } _cacheAge = DateTime.Now; }
public async Task UninstallPackage(PackageSpec package) { AbortOnInvalidConfiguration(); await _packageManager.UninstallAsync(package, this, _cancelAll.Token); }
internal PipPackageView(IPackageManager provider, PackageSpec package, bool isInstalled) { _provider = provider; _package = package; _isInstalled = isInstalled; }
public Task<PackageSpec> GetInstallablePackageAsync(PackageSpec package, CancellationToken cancellationToken) { return Task.FromResult(new PackageSpec()); }
public async Task <PackageSpec> GetPackageInfoAsync(PackageSpec entry, CancellationToken cancel) { string description = null; List <string> versions = null; lock (NotOnPyPI) { if (NotOnPyPI.Contains(entry.Name)) { return(new PackageSpec()); } } using (var client = new WebClient()) { Stream data; try { data = await client.OpenReadTaskAsync(new Uri(_index ?? DefaultIndex, entry.Name + "/json")); } catch (WebException ex) { if ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { lock (NotOnPyPI) { NotOnPyPI.Add(entry.Name); } } // No net access or no such package return(new PackageSpec()); } try { using (var reader = JsonReaderWriterFactory.CreateJsonReader(data, new XmlDictionaryReaderQuotas())) { var doc = XDocument.Load(reader); // TODO: Get package URL //url = (string)doc.Document // .Elements("root") // .Elements("info") // .Elements("package_url") // .FirstOrDefault(); description = (string)doc.Document .Elements("root") .Elements("info") .Elements("description") .FirstOrDefault(); versions = doc.Document .Elements("root") .Elements("releases") .Elements() .Attributes("item") .Select(a => a.Value) .ToList(); } } catch (InvalidOperationException) { } } bool changed = false; PackageSpec result; using (await _cacheLock.LockAsync(cancel)) { if (!_cache.TryGetValue(entry.Name, out result)) { result = _cache[entry.Name] = new PackageSpec(entry.Name); } if (!string.IsNullOrEmpty(description)) { var lines = description.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); var firstLine = string.Join( " ", lines.TakeWhile(s => !IsSeparatorLine(s)).Select(s => s.Trim()) ); if (firstLine.Length > 500) { firstLine = firstLine.Substring(0, 497) + "..."; } if (firstLine == "UNKNOWN") { firstLine = string.Empty; } result.Description = firstLine; changed = true; } if (versions != null) { var updateVersion = PackageVersion.TryParseAll(versions) .Where(v => v.IsFinalRelease) .OrderByDescending(v => v) .FirstOrDefault(); result.ExactVersion = updateVersion; changed = true; } } if (changed) { TriggerWriteCacheToDisk(); } return(result.Clone()); }