public static TestEnvironment GetOrCreate(PythonVersion pythonVersion, string testFramework, bool installFramework = true, bool installCoverage = false) { var testEnvironmentId = $"{pythonVersion.ToString().ToLower()}:{testFramework.ToLower()}:{installFramework.ToString()}:{installCoverage.ToString()}"; if (_environmentsMap.TryGetValue(testEnvironmentId, out TestEnvironment foundEnv)) { SetDirectories(foundEnv); return(foundEnv); } var env = new TestEnvironment(); env.TestFramework = testFramework; SetDirectories(env); switch (testFramework) { case "Pytest": { var envDir = TestData.GetTempPath(); var packages = new List <string>(); if (installFramework) { packages.Add("pytest"); } if (installCoverage) { packages.Add("coverage"); } pythonVersion.CreateVirtualEnv(envDir, packages); env.InterpreterPath = Path.Combine(envDir, "scripts", "python.exe"); } break; default: if (HasPackage(pythonVersion.PrefixPath, "pytest") || installCoverage) { // Create an empty virtual env to ensure we don't accidentally rely on pytest // (which was bug https://github.com/microsoft/PTVS/issues/5454) var envDir = TestData.GetTempPath(); var packages = new List <string>(); if (installCoverage) { packages.Add("coverage"); } pythonVersion.CreateVirtualEnv(envDir, packages); env.InterpreterPath = Path.Combine(envDir, "scripts", "python.exe"); } else { env.InterpreterPath = pythonVersion.InterpreterPath; } break; } _environmentsMap.Add(testEnvironmentId, env); return(env); }
private static string CreateWorkspaceFolder( string reqsFileContents = null, string envFileContents = null, string settingsFileContents = null, PythonVersion virtualEnvBase = null, string[] virtualEnvPackages = null ) { var workspaceFolder = TestData.GetTempPath(); File.WriteAllText( Path.Combine(workspaceFolder, "main.py"), string.Empty, Encoding.UTF8 ); if (reqsFileContents != null) { File.WriteAllText( Path.Combine(workspaceFolder, "requirements.txt"), reqsFileContents, Encoding.UTF8 ); } if (envFileContents != null) { File.WriteAllText( Path.Combine(workspaceFolder, "environment.yml"), envFileContents, Encoding.UTF8 ); } if (settingsFileContents != null) { File.WriteAllText( Path.Combine(workspaceFolder, "PythonSettings.json"), settingsFileContents, Encoding.UTF8 ); } if (virtualEnvBase != null) { virtualEnvBase.CreateVirtualEnv(Path.Combine(workspaceFolder, "env"), virtualEnvPackages); } return(workspaceFolder); }
/// <summary> /// Creates a Python virtual environment in specified directory and installs the specified packages. /// </summary> public static void CreateVirtualEnv(this PythonVersion pyVersion, string envPath, IEnumerable <string> packages) { pyVersion.CreateVirtualEnv(envPath); var envPythonExePath = Path.Combine(envPath, "scripts", "python.exe"); foreach (var package in packages.MaybeEnumerate()) { using (var output = ProcessOutput.RunHiddenAndCapture(envPythonExePath, "-m", "pip", "install", package)) { Assert.IsTrue(output.Wait(TimeSpan.FromSeconds(30))); Assert.AreEqual(0, output.ExitCode); } } }
private static string PrepareProject(PythonVisualStudioApp app, PythonVersion python, string formatter) { var slnPath = app.CopyProjectForTest(@"TestData\FormattingTests\FormattingTests.sln"); var projFolder = Path.GetDirectoryName(slnPath); var projPath = Path.Combine(projFolder, "FormattingTests.pyproj"); // The project file has a placeholder for the formatter which we must replace var projContents = File.ReadAllText(projPath); projContents = projContents.Replace("$$FORMATTER$$", formatter); File.WriteAllText(projPath, projContents); // The project references a virtual env in 'env' subfolder, // which we need to create before opening the project. python.CreateVirtualEnv(VirtualEnvName.First, new[] { formatter }, Path.Combine(projFolder, "env")); return(slnPath); }
private async Task DetectReqPkgMissingAsync(PythonVersion pythonInterpreter) { string virtualEnvPath = TestData.GetTempPath(); string interpreterExePath = Path.Combine(virtualEnvPath, "Scripts", "python.exe"); string reqTextPath = Path.Combine(virtualEnvPath, "requirements.txt"); var installPackages = new[] { "cookies >= 2.0", "Bottle==0.8.2" }; pythonInterpreter.CreateVirtualEnv(virtualEnvPath, installPackages); // Test cases for packages not missing bool isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsFalse(isPackageMissing, "Expected no missing packages because requirements.txt does not exist"); File.WriteAllText(reqTextPath, String.Empty); isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsFalse(isPackageMissing, "Expected no missing packages because requirements.txt is empty"); File.Delete(reqTextPath); File.WriteAllLines(reqTextPath, installPackages); File.AppendAllLines(reqTextPath, new string[] { " ", "$InvalidLineOfText ", "#MissingPackageName", " git+https://myvcs.com/some_dependency@", "coo kies", "cookies > = 100 ", "cookies >= 1.0 <= 2.0 flask == 2.0" }); isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsFalse(isPackageMissing, "Expected no missing packages because all packages are installed and invalid lines should be ignored"); File.Delete(reqTextPath); File.WriteAllLines(reqTextPath, installPackages, encoding: new UTF8Encoding(true)); isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsFalse(isPackageMissing, "Expected no missing packages because all packages are installed and UTF-8 BOM signature should be ignored"); File.Delete(reqTextPath); // Test cases for packages missing File.WriteAllLines(reqTextPath, new string[] { " MissingPackageName " }); isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsTrue(isPackageMissing, "Expected missing packages because \"MissingPackageName\" it is not installed"); File.Delete(reqTextPath); File.WriteAllLines(reqTextPath, new string[] { "Cookies<=1.0" }); isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsTrue(isPackageMissing, "Expected missing packages because \"cookies\" is incorrect version"); File.Delete(reqTextPath); File.WriteAllLines(reqTextPath, new string[] { "Cookies>=1.0", "Cookies>=100.0" }); isPackageMissing = await PipRequirementsUtils.DetectMissingPackagesAsync(interpreterExePath, reqTextPath); Assert.IsTrue(isPackageMissing, "Expected missing package because \"cookies\" has a valid and invalid package version"); File.Delete(reqTextPath); }