Example #1
0
        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 {
                    var envVars = await GetEnvironmentVariables();

                    using (var proc = ProcessOutput.Run(
                               _factory.Configuration.InterpreterPath,
                               args,
                               _factory.Configuration.GetPrefixPath(),
                               envVars,
                               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.GetSearchPathsAsync(
                            _factory.Configuration,
                            new FileSystem(new OSPlatform()),
                            new ProcessServices()
                            );

                        packages = await Task.Run(() => paths.Where(p => p.Type != PythonLibraryPathType.StdLib && 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();
        }
Example #2
0
        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 = new List <string>();
                args.Add("list");
                args.Add("-p");
                args.Add(ProcessOutput.QuoteSingleArgument(_factory.Configuration.PrefixPath));
                args.Add("--json");

                var concurrencyLock = alreadyHasConcurrencyLock ? null : await _concurrencyLock.LockAsync(cancellationToken);

                try {
                    using (var proc = ProcessOutput.Run(
                               _condaPath,
                               args,
                               _factory.Configuration.PrefixPath,
                               UnbufferedEnv,
                               false,
                               null
                               )) {
                        try {
                            if ((await proc) == 0)
                            {
                                var json = string.Join(Environment.NewLine, proc.StandardOutputLines);
                                try {
                                    var data = JArray.Parse(json);
                                    packages = data
                                               .Select(j => new PackageSpec(j.Value <string>("name"), j.Value <string>("version")))
                                               .Where(p => p.IsValid)
                                               .OrderBy(p => p.Name)
                                               .ToList();
                                } catch (Newtonsoft.Json.JsonException ex) {
                                    Debug.WriteLine("Failed to parse: {0}".FormatInvariant(ex.Message));
                                    Debug.WriteLine(json);
                                }
                            }
                        } catch (OperationCanceledException) {
                            // Process failed to run
                            Debug.WriteLine("Failed to run conda to collect installed packages");
                            foreach (var line in proc.StandardOutputLines)
                            {
                                Debug.WriteLine(line);
                            }
                        }
                    }
                } finally {
                    concurrencyLock?.Dispose();
                }

                // Outside of concurrency lock, still in working lock

                _installedPackages.Clear();
                if (packages != null)
                {
                    _installedPackages.AddRange(packages);
                }
                _everCached = true;
            } finally {
                workingLock?.Dispose();
            }

            InstalledPackagesChanged?.Invoke(this, EventArgs.Empty);
            _factory.NotifyImportNamesChanged();
        }