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)); }
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(); } }