Beispiel #1
0
        internal static IPythonInterpreterFactory CreateVirtualEnvironment(string pythonVersion, VisualStudioApp app, PythonProjectNode pyProj)
        {
            var uiThread = app.ServiceProvider.GetUIThread();
            var task     = uiThread.InvokeTask(() => {
                var model           = app.GetService <IComponentModel>(typeof(SComponentModel));
                var registryService = model.GetService <IInterpreterRegistryService>();
                var optionsService  = model.GetService <IInterpreterOptionsService>();

                return(VirtualEnv.CreateAndAddFactory(
                           app.ServiceProvider,
                           registryService,
                           optionsService,
                           pyProj,
                           null,
                           Path.Combine(pyProj.ProjectHome, "env"),
                           registryService.FindInterpreter("Global|PythonCore|" + pythonVersion + "-32"),
                           false,
                           null,
                           Version.Parse(pythonVersion) >= new Version(3, 3)
                           ));
            });

            try {
                Assert.IsTrue(task.Wait(TimeSpan.FromMinutes(2.0)), "Timed out waiting for venv");
            } catch (AggregateException ex) {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
            }
            var factory = task.Result;

            Assert.IsTrue(uiThread.Invoke(() => factory.Configuration.Id == pyProj.GetInterpreterFactory().Configuration.Id));
            return(factory);
        }
        private static IEnumerable <string> EnumerateAllFiles(
            string source,
            string filters,
            List <string> virtualEnvPaths
            )
        {
            var files    = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var patterns = filters.Split(';').Concat(new[] { "*.py" }).Select(p => p.Trim()).ToArray();

            var directories = new List <string>()
            {
                source
            };
            var skipDirectories = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            try {
                directories.AddRange(Directory.EnumerateDirectories(source, "*", SearchOption.AllDirectories));
            } catch (UnauthorizedAccessException) {
            }

            foreach (var dir in directories)
            {
                if (UnwindDirectory(dir).Any(skipDirectories.Contains))
                {
                    continue;
                }

                try {
                    if (virtualEnvPaths != null)
                    {
                        var origPrefix = VirtualEnv.GetOrigPrefixPath(dir);
                        if (!string.IsNullOrEmpty(origPrefix))
                        {
                            virtualEnvPaths.Add(dir);
                            skipDirectories.Add(CommonUtils.TrimEndSeparator(dir));
                            continue;
                        }
                    }

                    foreach (var filter in patterns)
                    {
                        files.UnionWith(Directory.EnumerateFiles(dir, filter));
                    }
                } catch (UnauthorizedAccessException) {
                }
            }

            return(files
                   .Where(path => path.StartsWith(source))
                   .Select(path => path.Substring(source.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
                   .Distinct(StringComparer.OrdinalIgnoreCase));
        }
Beispiel #3
0
        internal static void WriteProjectXml(
            IInterpreterRegistryService service,
            TextWriter writer,
            string projectPath,
            string sourcePath,
            string filters,
            string searchPaths,
            string startupFile,
            PythonInterpreterView selectedInterpreter,
            ProjectCustomization customization,
            bool detectVirtualEnv
            )
        {
            var projectHome = PathUtils.GetRelativeDirectoryPath(Path.GetDirectoryName(projectPath), sourcePath);

            var project = ProjectRootElement.Create();

            project.DefaultTargets = "Build";
            project.ToolsVersion   = "4.0";

            var globals = project.AddPropertyGroup();

            globals.AddProperty("Configuration", "Debug").Condition = " '$(Configuration)' == '' ";
            globals.AddProperty("SchemaVersion", "2.0");
            globals.AddProperty("ProjectGuid", Guid.NewGuid().ToString("B"));
            globals.AddProperty("ProjectHome", projectHome);
            if (PathUtils.IsValidPath(startupFile))
            {
                globals.AddProperty("StartupFile", startupFile);
            }
            else
            {
                globals.AddProperty("StartupFile", "");
            }
            globals.AddProperty("SearchPath", searchPaths);
            globals.AddProperty("WorkingDirectory", ".");
            globals.AddProperty("OutputPath", ".");

            globals.AddProperty("ProjectTypeGuids", "{888888a0-9f3d-457c-b088-3a5042f75d52}");
            globals.AddProperty("LaunchProvider", DefaultLauncherProvider.DefaultLauncherName);

            var interpreterId = globals.AddProperty(PythonConstants.InterpreterId, "");

            if (selectedInterpreter != null && !String.IsNullOrWhiteSpace(selectedInterpreter.Id))
            {
                interpreterId.Value = selectedInterpreter.Id;
            }

            // VS requires property groups with conditions for Debug
            // and Release configurations or many COMExceptions are
            // thrown.
            var debugGroup   = project.AddPropertyGroup();
            var releaseGroup = project.AddPropertyGroup();

            debugGroup.Condition   = "'$(Configuration)' == 'Debug'";
            releaseGroup.Condition = "'$(Configuration)' == 'Release'";


            var folders         = new HashSet <string>();
            var virtualEnvPaths = detectVirtualEnv ? new List <string>() : null;

            foreach (var unescapedFile in EnumerateAllFiles(sourcePath, filters, virtualEnvPaths))
            {
                var file     = ProjectCollection.Escape(unescapedFile);
                var ext      = Path.GetExtension(file);
                var fileType = "Content";
                if (PythonConstants.FileExtension.Equals(ext, StringComparison.OrdinalIgnoreCase) ||
                    PythonConstants.WindowsFileExtension.Equals(ext, StringComparison.OrdinalIgnoreCase))
                {
                    fileType = "Compile";
                }
                folders.Add(Path.GetDirectoryName(file));

                project.AddItem(fileType, file);
            }

            foreach (var folder in folders.Where(s => !string.IsNullOrWhiteSpace(s)).OrderBy(s => s))
            {
                project.AddItem("Folder", folder);
            }

            if (selectedInterpreter != null && !String.IsNullOrWhiteSpace(selectedInterpreter.Id))
            {
                project.AddItem(
                    MSBuildConstants.InterpreterReferenceItem,
                    selectedInterpreter.Id
                    );
            }
            if (virtualEnvPaths != null && virtualEnvPaths.Any() && service != null)
            {
                foreach (var path in virtualEnvPaths)
                {
                    var shortId = PathUtils.GetFileOrDirectoryName(path);
                    var longId  = MSBuildProjectInterpreterFactoryProvider.GetInterpreterId("$(MSBuildProjectFullPath)", shortId);
                    var config  = VirtualEnv.FindInterpreterConfiguration(longId, path, service);
                    if (config != null)
                    {
                        AddVirtualEnvironment(project, sourcePath, shortId, config);

                        if (string.IsNullOrEmpty(interpreterId.Value))
                        {
                            interpreterId.Value = longId;
                        }
                    }
                }
            }

            var imports = project.AddPropertyGroup();

            imports.AddProperty("VisualStudioVersion", "10.0").Condition = " '$(VisualStudioVersion)' == '' ";

            (customization ?? DefaultProjectCustomization.Instance).Process(
                sourcePath,
                project,
                new Dictionary <string, ProjectPropertyGroupElement> {
                { "Globals", globals },
                { "Imports", imports },
                { "Debug", debugGroup },
                { "Release", releaseGroup }
            }
                );

            project.Save(writer);
        }
        private void CustomEnvironmentPrefixPathChanged()
        {
            if (IsCustomInterpreter)
            {
                if (Directory.Exists(PrefixPath))
                {
                    IsCustomPrefixPathValid = true;

                    var config = VirtualEnv.FindInterpreterConfiguration(null, PrefixPath, RegistryService);
                    if (config != null && File.Exists(config.InterpreterPath))
                    {
                        var baseInterp = _allGlobalInterpreters.FirstOrDefault(v => v.Id == config.Id);

                        IsRegisterCustomEnvEnabled = SelectedProject != null;
                        RegisterCustomEnv          = SelectedProject == null;
                        IsCustomVirtualEnv         = baseInterp != null;
                        IsCustomNotVirtualEnv      = baseInterp == null;

                        SetCustomVariables(config);
                    }
                    else
                    {
                        IsRegisterCustomEnvEnabled = SelectedProject != null;
                        RegisterCustomEnv          = true;
                        IsCustomNotVirtualEnv      = true;
                        IsCustomVirtualEnv         = false;

                        ClearCustomVariables();

                        AutoDetectFromCustomPrefixPathAsync().DoNotWait();
                    }

                    ValidateCustomData();
                }
                else
                {
                    IsRegisterCustomEnvEnabled = false;
                    RegisterCustomEnv          = false;
                    IsCustomPrefixPathValid    = false;
                    IsCustomNotVirtualEnv      = false;
                    IsCustomVirtualEnv         = false;

                    // For now, we enable but prompt when they click accept
                    //IsAcceptEnabled = false;
                    IsAcceptEnabled = true;

                    ClearCustomVariables();
                }
            }
            else
            {
                IsRegisterCustomEnvEnabled = false;
                RegisterCustomEnv          = false;
                IsCustomPrefixPathValid    = false;
                IsCustomNotVirtualEnv      = false;
                IsCustomVirtualEnv         = false;
                IsAcceptEnabled            = true;

                ClearCustomVariables();
            }
        }