private static void LogEvent(JTypeDatabaseCreationRequest request, string contents) { for (int i = 0; i < 10; i++) { try { File.AppendAllText( GetLogFilename(), String.Format( "\"{0}\" \"{1}\" \"{2}\" \"{3}\"{4}", DateTime.Now.ToString("yyyy/MM/dd h:mm:ss.fff tt"), request.Factory.Configuration.InterpreterPath, request.OutputPath, contents, Environment.NewLine ) ); return; } catch (IOException) { // racing with someone else generating? Thread.Sleep(25); } } }
private static string BuildArguments(JTypeDatabaseCreationRequest request, string outPath, string libDir, string virtualEnvPackages) { string args = "/dir " + "\"" + libDir + "\"" + " /version V" + request.Factory.Configuration.Version.ToString().Replace(".", "") + " /outdir " + "\"" + outPath + "\"" + " /indir " + "\"" + outPath + "\""; if (virtualEnvPackages != null) { args += " /dir \"" + virtualEnvPackages + "\""; } return args; }
private static void GetLibDirs(JTypeDatabaseCreationRequest request, out string libDir, out string virtualEnvPackages) { libDir = Path.Combine(Path.GetDirectoryName(request.Factory.Configuration.InterpreterPath), "Lib"); virtualEnvPackages = null; if (!Directory.Exists(libDir)) { string virtualEnvLibDir = Path.Combine(Path.GetDirectoryName(request.Factory.Configuration.InterpreterPath), "..\\Lib"); string prefixFile = Path.Combine(virtualEnvLibDir, "orig-prefix.txt"); if (Directory.Exists(virtualEnvLibDir) && File.Exists(prefixFile)) { // virtual env is setup differently. The EXE is in a Scripts directory with the Lib dir being at ..\Lib // relative to the EXEs dir. There is alos an orig-prefix.txt which points at the normal full J // install. Parse that file and include the normal J install in the analysis. try { var lines = File.ReadAllLines(Path.Combine(prefixFile)); if (lines.Length >= 1 && lines[0].IndexOfAny(Path.GetInvalidPathChars()) == -1) { string origLibDir = Path.Combine(lines[0], "Lib"); if (Directory.Exists(origLibDir)) { // virtual env install libDir = origLibDir; virtualEnvPackages = Path.Combine(virtualEnvLibDir, "site-packages"); } } } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (System.Security.SecurityException) { } } else { // try and find the lib dir based upon where site.py lives var psi = new ProcessStartInfo( request.Factory.Configuration.InterpreterPath, "-c \"import site; print site.__file__\"" ); psi.RedirectStandardOutput = true; psi.RedirectStandardError = true; psi.UseShellExecute = false; psi.CreateNoWindow = true; var proc = Process.Start(psi); OutputDataReceiver receiver = new OutputDataReceiver(); proc.OutputDataReceived += receiver.OutputDataReceived; proc.ErrorDataReceived += receiver.OutputDataReceived; proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); proc.WaitForExit(); string siteFilename = receiver.Received.ToString().Trim(); if (!String.IsNullOrWhiteSpace(siteFilename) && siteFilename.IndexOfAny(Path.GetInvalidPathChars()) == -1) { var dirName = Path.GetDirectoryName(siteFilename); if (Directory.Exists(dirName)) { libDir = dirName; } } } } }
/// <summary> /// Creates a new completion database based upon the specified request. Calls back the provided delegate when /// the generation has finished. /// </summary> public static bool Generate(JTypeDatabaseCreationRequest request, Action databaseGenerationCompleted) { if (String.IsNullOrEmpty(request.Factory.Configuration.InterpreterPath)) { return false; } string outPath = request.OutputPath; Thread t = new Thread(x => { if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } var psi = new ProcessStartInfo(); psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.FileName = request.Factory.Configuration.InterpreterPath; psi.Arguments = "\"" + Path.Combine(GetJToolsInstallPath(), "JScraper.py") + "\"" + // script to run " \"" + outPath + "\"" + // output dir " \"" + GetBaselineDatabasePath() + "\""; // baseline file psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; var proc = new Process(); proc.StartInfo = psi; StringBuilder output = new StringBuilder(); try { LogEvent(request, "START_SCRAPE " + psi.Arguments); proc.Start(); proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); proc.OutputDataReceived += (sender, args) => output.AppendLine(args.Data); proc.ErrorDataReceived += (sender, args) => output.AppendLine(args.Data); proc.WaitForExit(); LogEvent(request, "OUTPUT\r\n " + output.Replace("\r\n", "\r\n ")); } catch (Win32Exception ex) { // failed to start process, interpreter doesn't exist? LogEvent(request, "FAIL_SCRAPE " + ex.ToString().Replace("\r\n", " -- ")); LogEvent(request, " " + output.Replace("\r\n", "\r\n ")); databaseGenerationCompleted(); return; } if (proc.ExitCode != 0) { LogEvent(request, "FAIL_SCRAPE " + proc.ExitCode); } else { LogEvent(request, "DONE (SCRAPE)"); } if ((request.DatabaseOptions & GenerateDatabaseOptions.StdLibDatabase) != 0) { psi = new ProcessStartInfo(); psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.FileName = Path.Combine(GetJToolsInstallPath(), "J.Tools.Analyzer.exe"); string libDir; string virtualEnvPackages; GetLibDirs(request, out libDir, out virtualEnvPackages); if (File.Exists(psi.FileName)) { psi.Arguments = BuildArguments(request, outPath, libDir, virtualEnvPackages); proc = new Process(); proc.StartInfo = psi; try { LogEvent(request, "START_STDLIB " + psi.Arguments); proc.Start(); proc.WaitForExit(); if (proc.ExitCode == 0) { LogEvent(request, "DONE (STDLIB)"); } else { LogEvent(request, "FAIL_STDLIB " + proc.ExitCode); } } catch (Win32Exception ex) { // failed to start the process LogEvent(request, "FAIL_STDLIB " + ex.ToString().Replace("\r\n", " -- ")); } databaseGenerationCompleted(); } } else { databaseGenerationCompleted(); } }); t.Start(); return true; }