public void UnavailableEnvironments() { var collection = new Microsoft.Build.Evaluation.ProjectCollection(); try { var service = new MockInterpreterOptionsService(); var proj = collection.LoadProject(TestData.GetPath(@"TestData\Environments\Unavailable.pyproj")); using (var provider = new MSBuildProjectInterpreterFactoryProvider(service, proj)) { try { provider.DiscoverInterpreters(); Assert.Fail("Expected InvalidDataException in DiscoverInterpreters"); } catch (InvalidDataException ex) { AssertUtil.AreEqual(ex.Message .Replace(TestData.GetPath("TestData\\Environments\\"), "$") .Split('\r', '\n') .Where(s => !string.IsNullOrEmpty(s)) .Select(s => s.Trim()), "Some project interpreters failed to load:", @"Interpreter $env\ has invalid value for 'Id': INVALID ID", @"Interpreter $env\ has invalid value for 'Version': INVALID VERSION", @"Base interpreter $env\ has invalid value for 'BaseInterpreter': INVALID BASE", @"Interpreter $env\ has invalid value for 'InterpreterPath': INVALID<>PATH", @"Interpreter $env\ has invalid value for 'WindowsInterpreterPath': INVALID<>PATH", @"Interpreter $env\ has invalid value for 'LibraryPath': INVALID<>PATH", @"Base interpreter $env\ has invalid value for 'BaseInterpreter': {98512745-4ac7-4abb-9f33-120af32edc77}" ); } var factories = provider.GetInterpreterFactories().ToList(); foreach (var fact in factories) { Console.WriteLine("{0}: {1}", fact.GetType().FullName, fact.Description); } foreach (var fact in factories) { Assert.IsInstanceOfType( fact, typeof(MSBuildProjectInterpreterFactoryProvider.NotFoundInterpreterFactory), string.Format("{0} was not correct type", fact.Description) ); Assert.IsFalse(provider.IsAvailable(fact), string.Format("{0} was not unavailable", fact.Description)); } AssertUtil.AreEqual(factories.Select(f => f.Description), "Invalid BaseInterpreter (unavailable)", "Invalid InterpreterPath (unavailable)", "Invalid WindowsInterpreterPath (unavailable)", "Invalid LibraryPath (unavailable)", "Absent BaseInterpreter (unavailable)", "Unknown Python 2.7" ); } } finally { collection.UnloadAllProjects(); collection.Dispose(); } }
public ProjectInfo(IVsProject project, TestContainerDiscoverer discoverer, MSBuildProjectInterpreterFactoryProvider factoryProvider) { Project = project; Discoverer = discoverer; FactoryProvider = factoryProvider; ActiveInterpreter = FactoryProvider.ActiveInterpreter; Attach(); HookNewDatabaseAvailable(); }
public void UnavailableEnvironments() { var collection = new Microsoft.Build.Evaluation.ProjectCollection(); try { var service = new MockInterpreterOptionsService(); var proj = collection.LoadProject(TestData.GetPath(@"TestData\Environments\Unavailable.pyproj")); var contextProvider = new MockProjectContextProvider(proj); var logger = new MockLogger(); using (var provider = new MSBuildProjectInterpreterFactoryProvider( new[] { new Lazy <IProjectContextProvider>(() => contextProvider) }, null, new[] { new Lazy <IInterpreterLog>(() => logger) })) { var configs = provider.GetInterpreterConfigurations().ToArray(); // force the load... AssertUtil.AreEqual( logger.Errors.ToString() .Replace(TestData.GetPath("TestData\\Environments\\"), "$") .Split('\r', '\n') .Where(s => !string.IsNullOrEmpty(s)) .Select(s => s.Trim()), @"Interpreter $env\ has invalid value for 'Id':", @"Interpreter $env\ has invalid value for 'Version': INVALID VERSION", @"Interpreter $env\ has invalid value for 'InterpreterPath': INVALID<>PATH", @"Interpreter $env\ has invalid value for 'WindowsInterpreterPath': INVALID<>PATH" ); var factories = provider.GetInterpreterFactories().ToList(); foreach (var fact in factories) { Console.WriteLine("{0}: {1}", fact.GetType().FullName, fact.Configuration.Description); } foreach (var fact in factories) { Assert.IsInstanceOfType( fact, typeof(NotFoundInterpreterFactory), string.Format("{0} was not correct type", fact.Configuration.Description) ); Assert.IsFalse(fact.Configuration.IsAvailable(), string.Format("{0} was not unavailable", fact.Configuration.Description)); } AssertUtil.AreEqual(factories.Select(f => f.Configuration.Description), "Invalid InterpreterPath (unavailable)", "Invalid WindowsInterpreterPath (unavailable)" ); } } finally { collection.UnloadAllProjects(); collection.Dispose(); } }
public InterpretersNode( PythonProjectNode project, ProjectItem item, IPythonInterpreterFactory factory, bool isInterpreterReference, bool canDelete, bool canRemove = true, string captionSuffix = null ) : base(project, ChooseElement(project, item)) { ExcludeNodeFromScc = true; _interpreters = project.Interpreters; _interpreterService = project.Site.GetComponentModel().GetService <IInterpreterOptionsService>(); _factory = factory; _isReference = isInterpreterReference; _canDelete = canDelete; _canRemove = canRemove; _captionSuffix = captionSuffix ?? ""; if (Directory.Exists(_factory.Configuration.LibraryPath)) { // TODO: Need to handle watching for creation try { _fileWatcher = new FileSystemWatcher(_factory.Configuration.LibraryPath); } catch (ArgumentException) { // Path was not actually valid, despite Directory.Exists // returning true. } if (_fileWatcher != null) { try { _fileWatcher.IncludeSubdirectories = true; _fileWatcher.Deleted += PackagesChanged; _fileWatcher.Created += PackagesChanged; _fileWatcher.EnableRaisingEvents = true; // Only create the timer if the file watcher is running. _timer = new Timer(CheckPackages); } catch (IOException) { // Raced with directory deletion _fileWatcher.Dispose(); _fileWatcher = null; } } } }
public string GetCurrentTest(string filePath, int line, int lineCharOffset) { var project = PathToProject(filePath); if (project != null && _discoverer.IsProjectKnown(project)) { var buildEngine = new MSBuild.ProjectCollection(); string projectPath; if (project.TryGetProjectPath(out projectPath)) { var proj = buildEngine.LoadProject(projectPath); #if FALSE var provider = new MSBuildProjectInterpreterFactoryProvider(_interpreterService, proj); try { provider.DiscoverInterpreters(); } catch (InvalidDataException) { // This exception can be safely ignored here. } var factory = provider.ActiveInterpreter; var parser = Parser.CreateParser( new StreamReader(filePath), factory.GetLanguageVersion() ); var ast = parser.ParseFile(); var walker = new FunctionFinder(ast, line, lineCharOffset); ast.Walk(walker); var projHome = Path.GetFullPath(Path.Combine(proj.DirectoryPath, proj.GetPropertyValue(PythonConstants.ProjectHomeSetting) ?? ".")); if (walker.ClassName != null && walker.FunctionName != null) { return(TestAnalyzer.MakeFullyQualifiedTestName( CommonUtils.CreateFriendlyFilePath(projHome, filePath), walker.ClassName, walker.FunctionName )); } #endif } } return(null); }
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); }
public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { ValidateArg.NotNull(sources, "sources"); ValidateArg.NotNull(discoverySink, "discoverySink"); var buildEngine = new MSBuild.ProjectCollection(); try { // Load all the test containers passed in (.pyproj msbuild files) foreach (string source in sources) { buildEngine.LoadProject(source); } foreach (var proj in buildEngine.LoadedProjects) { using (var provider = new MSBuildProjectInterpreterFactoryProvider(_interpreterService, proj)) { try { provider.DiscoverInterpreters(); } catch (InvalidDataException) { // This exception can be safely ignored here. } var factory = provider.ActiveInterpreter; if (factory == _interpreterService.NoInterpretersValue) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "No interpreters available for project " + proj.FullPath); } continue; } var projectHome = Path.GetFullPath(Path.Combine(proj.DirectoryPath, proj.GetPropertyValue(PythonConstants.ProjectHomeSetting) ?? ".")); // Do the analysis even if the database is not up to date. At // worst, we'll get no results. using (var analyzer = new TestAnalyzer( factory, proj.FullPath, projectHome, TestExecutor.ExecutorUri )) { // Provide all files to the test analyzer foreach (var item in proj.GetItems("Compile")) { string fileAbsolutePath = CommonUtils.GetAbsoluteFilePath(projectHome, item.EvaluatedInclude); string fullName; try { fullName = ModulePath.FromFullPath(fileAbsolutePath).ModuleName; } catch (ArgumentException) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "File has an invalid module name: " + fileAbsolutePath); } continue; } try { using (var reader = new StreamReader(fileAbsolutePath)) { analyzer.AddModule(fullName, fileAbsolutePath, reader); } } catch (FileNotFoundException) { // user deleted file, we send the test update, but the project // isn't saved. #if DEBUG } catch (Exception ex) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "Failed to discover tests in " + fileAbsolutePath); logger.SendMessage(TestMessageLevel.Informational, ex.ToString()); } } #else } catch (Exception) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "Failed to discover tests in " + fileAbsolutePath); } } #endif }
public bool Execute() { bool returnActive; Guid id; Version version; returnActive = !Guid.TryParse(InterpreterId, out id); if (!Version.TryParse(InterpreterVersion, out version)) { if (!returnActive) { _log.LogError( "Invalid values for InterpreterId (\"{0}\") and InterpreterVersion (\"{1}\")", InterpreterId, InterpreterVersion ); return(false); } } MSBuildProjectInterpreterFactoryProvider provider = null; ProjectCollection collection = null; Project project = null; var service = ServiceHolder.Create(); if (service == null) { _log.LogError("Unable to obtain interpreter service."); return(false); } try { try { project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(_projectPath).Single(); } catch (InvalidOperationException) { // Could not get exactly one project matching the path. } if (project == null) { collection = new ProjectCollection(); project = collection.LoadProject(_projectPath); } var projectHome = PathUtils.GetAbsoluteDirectoryPath( project.DirectoryPath, project.GetPropertyValue("ProjectHome") ); var searchPath = project.GetPropertyValue("SearchPath"); if (!string.IsNullOrEmpty(searchPath)) { SearchPaths = searchPath.Split(';') .Select(p => PathUtils.GetAbsoluteFilePath(projectHome, p)) .ToArray(); } else { SearchPaths = new string[0]; } provider = new MSBuildProjectInterpreterFactoryProvider(service.Service, project); try { provider.DiscoverInterpreters(); } catch (InvalidDataException ex) { _log.LogWarning("Errors while resolving environments: {0}", ex.Message); } IPythonInterpreterFactory factory = null; if (returnActive) { factory = provider.ActiveInterpreter; } else { factory = provider.FindInterpreter(id, version); } if (!provider.IsAvailable(factory)) { _log.LogError( "The environment '{0}' is not available. Check your project configuration and try again.", factory.Description ); return(false); } else if (factory == service.Service.NoInterpretersValue) { _log.LogError( "No Python environments are configured. Please install or configure an environment and try " + "again. See http://go.microsoft.com/fwlink/?LinkID=299429 for information on setting up a " + "Python environment." ); return(false); } else if (factory != null) { PrefixPath = PathUtils.EnsureEndSeparator(factory.Configuration.PrefixPath); if (PathUtils.IsSubpathOf(projectHome, PrefixPath)) { ProjectRelativePrefixPath = PathUtils.GetRelativeDirectoryPath(projectHome, PrefixPath); } else { ProjectRelativePrefixPath = string.Empty; } InterpreterPath = factory.Configuration.InterpreterPath; WindowsInterpreterPath = factory.Configuration.WindowsInterpreterPath; LibraryPath = PathUtils.EnsureEndSeparator(factory.Configuration.LibraryPath); Architecture = factory.Configuration.Architecture.ToString(); PathEnvironmentVariable = factory.Configuration.PathEnvironmentVariable; Description = factory.Description; MajorVersion = factory.Configuration.Version.Major.ToString(); MinorVersion = factory.Configuration.Version.Minor.ToString(); return(true); } else if (returnActive) { _log.LogError("Unable to resolve active environment."); } else { _log.LogError("Unable to resolve environment {0} {1}", InterpreterId, InterpreterVersion); } } catch (Exception ex) { _log.LogErrorFromException(ex); } finally { if (provider != null) { provider.Dispose(); } if (collection != null) { collection.UnloadAllProjects(); collection.Dispose(); } service.Dispose(); } _log.LogError("Unable to resolve environment"); return(false); }