public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) { var project = pHierarchy.ToProject(); if (!project.IsGaugeProject()) { return(VSConstants.S_OK); } var slugifiedName = project.SlugifiedName(); if (GaugeService.Instance.ContainsApiConnectionFor(slugifiedName)) { return(VSConstants.S_OK); } try { StatusBarLogger.Log($"Initializing Gauge daemon for Project: {project.Name}"); GaugeService.Instance.RegisterGaugeProject(project, _gaugeDaemonOptions.MinPortRange, _gaugeDaemonOptions.MaxPortRange); StatusBarLogger.Log($"Initializing Gauge Project Cache: {project.Name}"); ProjectFactory.Initialize(project); } catch (Exception ex) { OutputPaneLogger.Error($"Failed to start Gauge Daemon: {ex}"); return(VSConstants.S_FALSE); } return(VSConstants.S_OK); }
public IEnumerable <Concept> GetAllConcepts() { if (_project == null) { OutputPaneLogger.Error("Error occurred GetAllConcepts: _project is null"); return(Enumerable.Empty <Concept>()); } var gaugeApiConnection = GaugeService.Instance.GetApiConnectionFor(_project); if (gaugeApiConnection == null) { OutputPaneLogger.Error("Error occurred GetAllConcepts: apiConnection is null"); return(Enumerable.Empty <Concept>()); } var conceptsRequest = new GetAllConceptsRequest(); var apiMessage = new APIMessage { MessageId = GenerateMessageId(), MessageType = APIMessage.Types.APIMessageType.GetAllConceptsRequest, AllConceptsRequest = conceptsRequest }; var bytes = gaugeApiConnection.WriteAndReadApiMessage(apiMessage); return(bytes.AllConceptsResponse.Concepts.Select(info => new Concept(_project) { StepText = info.StepValue.ParameterizedStepValue, StepValue = info.StepValue.StepValue, FilePath = info.Filepath, LineNumber = info.LineNumber })); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { ThreadHelper.ThrowIfNotOnUIThread(); if (VsShellUtilities.IsInAutomationFunction(_serviceProvider)) { return(Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } if ((VSConstants.VSStd2KCmdID)nCmdID != VSConstants.VSStd2KCmdID.FORMATDOCUMENT) { return(Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } var gaugeFile = new FileInfo(GaugePackage.DTE.ActiveDocument.FullName); var p = GaugeProcess.ForFormat(gaugeFile.DirectoryName, gaugeFile.Name); p.Start(); p.WaitForExit(); if (p.ExitCode != 0) { OutputPaneLogger.Error($"gauge format {gaugeFile.Name}\nSTDOUT:\n{p.StandardOutput.ReadToEnd()}\nSTDERR:\n{p.StandardError.ReadToEnd()}\n"); } return(VSConstants.S_OK); }
private IGaugeApiConnection StartGaugeAsDaemon(Project gaugeProject, int minPortRange, int maxPortRange) { var slugifiedName = gaugeProject.SlugifiedName(); if (ChildProcesses.ContainsKey(slugifiedName)) { if (ChildProcesses[slugifiedName].HasExited) { KillChildProcess(slugifiedName); } else { return(ApiConnections[slugifiedName]); } } var projectOutputPath = GetValidProjectOutputPath(gaugeProject); var port = GetOpenPort(minPortRange, maxPortRange); OutputPaneLogger.Debug("Opening Gauge Daemon for Project : {0}, at port: {1}", gaugeProject.Name, port); var environmentVariables = new Dictionary <string, string> { { "GAUGE_API_PORT", port.ToString(CultureInfo.InvariantCulture) }, { "gauge_custom_build_path", projectOutputPath } }; var gaugeProcess = GaugeProcess.ForDaemon(GetProjectRoot(gaugeProject), environmentVariables); gaugeProcess.Exited += (s, e) => OutputPaneLogger.Error( $"PID {gaugeProcess.Id} has exited with exit code {gaugeProcess.ExitCode}.\nSTDOUT:\n{gaugeProcess.StandardOutput.ReadToEnd()}\nSTDERR\n{gaugeProcess.StandardError.ReadToEnd()}"); gaugeProcess.OutputDataReceived += (sender, args) => { if (args.Data.StartsWith("Gauge daemon initialized")) { _initialized = true; } }; if (!gaugeProcess.Start()) { throw new GaugeApiInitializationException(gaugeProcess.StandardOutput.ReadToEnd(), gaugeProcess.StandardError.ReadToEnd()); } gaugeProcess.BeginOutputReadLine(); OutputPaneLogger.Debug("Opening Gauge Daemon with PID: {0}", gaugeProcess.Id); WaitForColdStart(); var tcpClientWrapper = new TcpClientWrapper(port); ApiPorts.Add(slugifiedName, port); ChildProcesses.Add(slugifiedName, gaugeProcess.BaseProcess); OutputPaneLogger.Debug("PID: {0} ready, waiting for messages..", gaugeProcess.Id); return(new GaugeApiConnection(tcpClientWrapper)); }
private static string GetValidProjectOutputPath(Project gaugeProject) { var projectOutputPath = gaugeProject.GetProjectOutputPath(); if (string.IsNullOrEmpty(projectOutputPath)) { OutputPaneLogger.Error( "Unable to retrieve Project Output path for Project : {0}. Not starting Gauge Daemon", gaugeProject.Name); throw new GaugeApiInitializationException("", $"Unable to retrieve Project Output path for Project : {gaugeProject.Name}"); } if (Directory.Exists(projectOutputPath)) { return(projectOutputPath); } OutputPaneLogger.Error("Project Output path '{0}' does not exists. Not starting Gauge Daemon", projectOutputPath); throw new GaugeApiInitializationException("", $"Project Output path '{projectOutputPath}' does not exists"); }
public static void DisplayGaugeNotStartedMessage(GaugeDisplayErrorLevel errorLevel, string dialogMessage, string errorMessageFormat, params object[] args) { var uiShell = (IVsUIShell)Package.GetGlobalService(typeof(IVsUIShell)); var clsId = Guid.Empty; var result = 0; OutputPaneLogger.Error(string.Format(errorMessageFormat, args)); OLEMSGICON msgicon; switch (errorLevel) { case GaugeDisplayErrorLevel.Info: msgicon = OLEMSGICON.OLEMSGICON_INFO; break; case GaugeDisplayErrorLevel.Warning: msgicon = OLEMSGICON.OLEMSGICON_WARNING; break; case GaugeDisplayErrorLevel.Error: msgicon = OLEMSGICON.OLEMSGICON_CRITICAL; break; default: msgicon = OLEMSGICON.OLEMSGICON_NOICON; break; } uiShell.ShowMessageBox(0, ref clsId, "Gauge - Error Occurred", dialogMessage, string.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, msgicon, 0, out result ); }
private bool ProcessIncludeLinkNavigate(Match match) { string IncludeFileFolderName = ""; string IncludeRegion = ""; if (match.Groups["IncludeFileRegion"].Value.Contains("#")) { IncludeFileFolderName = match.Groups["IncludeFileRegion"].Value.Split('#')[0]; IncludeRegion = match.Groups["IncludeFileRegion"].Value.Split('#')[1]; } else { IncludeFileFolderName = match.Groups["IncludeFileRegion"].Value; } bool IsURLProblem = false; bool bChangedLanguage = false; string FileNameLocation = ""; if (String.IsNullOrWhiteSpace(IncludeFileFolderName)) { if (String.IsNullOrWhiteSpace(IncludeRegion)) { log.Error(MarkdownSharp.Language.Message("UnableToNavigateToPage") + MarkdownSharp.Language.Message("ExcerptRegionToIncludeWhenNoFileGiven")); IsURLProblem = true; } else { //Assume that this is a reference to a location in this file IncludeFileFolderName = CurrentFolderFromMarkdownAsTopLeaf; } } if (IncludeFileFolderName.ToUpper().Contains("%ROOT%")) { IncludeFileFolderName = "."; } if (!IsURLProblem) { //We know location of file we want but not the file name AbsoluteMarkdownPath\IncludeFileName\*.Language.udn if (!Directory.Exists(Path.Combine(AbsoluteMarkdownPath, IncludeFileFolderName))) { //unable to locate the path to the file raise error log.Error(MarkdownSharp.Language.Message("BadPathForIncludeFile", match.Groups[0].Value)); IsURLProblem = true; } else { FileInfo[] LanguageFileInfo = new DirectoryInfo(Path.Combine(AbsoluteMarkdownPath, IncludeFileFolderName)).GetFiles("*." + Language + ".udn"); if (LanguageFileInfo.Length > 0) { FileNameLocation = LanguageFileInfo[0].FullName; } else { // File not found // if this is not an INT file check for the INT version. if (!Language.Equals("INT")) { LanguageFileInfo = new DirectoryInfo(Path.Combine(AbsoluteMarkdownPath, IncludeFileFolderName)).GetFiles("*.INT.udn"); if (LanguageFileInfo.Length == 0) { //unable to locate an INT file to replace the language raise error log.Error(MarkdownSharp.Language.Message("UnableToNavigateToPage") + MarkdownSharp.Language.Message("BadIncludeOrMissingMarkdownFileAndNoINTFile", match.Groups[0].Value)); IsURLProblem = true; } else { FileNameLocation = (LanguageFileInfo[0].FullName); //Raise info so that know we are allowing missing linked files to still allow processing of the file if INT file is there log.Info(MarkdownSharp.Language.Message("NavigatingToINTPage") + MarkdownSharp.Language.Message("BadIncludeOrMissingMarkdownFileINTUsed", match.Groups[0].Value)); IsURLProblem = true; bChangedLanguage = true; } } else { log.Error(MarkdownSharp.Language.Message("UnableToNavigateToPage") + MarkdownSharp.Language.Message("BadIncludeOrMissingMarkdownFile", match.Groups[0].Value)); IsURLProblem = true; } } } } // If no problem detected if (!IsURLProblem || bChangedLanguage) { if (String.IsNullOrWhiteSpace(IncludeRegion)) { //No region to consider, navigate straight to the page. DTE2 dte = Package.GetGlobalService(typeof(DTE)) as DTE2; //File found open it, this also makes the editor switch tabs to this file, so the preview window updates. dte.ItemOperations.OpenFile(FileNameLocation); return(true); } else { //Are we able to navigate to a region in the file? string IncludeFile = File.ReadAllText(FileNameLocation); Match Excerpts = Regex.Match(IncludeFile, Markdown.GetSubRegionOfFileMatcher(IncludeRegion)); if (Excerpts.Success) { //Found excerpt section, get the line number int LineNumber = 0; for (int i = 0; i <= Excerpts.Groups[0].Index - 1; ++i) { if (IncludeFile[i] == '\n') { ++LineNumber; } } DTE2 dte = Package.GetGlobalService(typeof(DTE)) as DTE2; //File found open it, this also makes the editor switch tabs to this file, so the preview window updates. dte.ItemOperations.OpenFile(FileNameLocation); dte.ExecuteCommand("Edit.Goto", LineNumber.ToString()); } else { //Region not found log.Error(MarkdownSharp.Language.Message("UnableToNavigateToPage") + MarkdownSharp.Language.Message("NotAbleToFindRegionInFile", match.Groups[0].Value)); IsURLProblem = true; DTE2 dte = Package.GetGlobalService(typeof(DTE)) as DTE2; //File found open it, this also makes the editor switch tabs to this file, so the preview window updates. dte.ItemOperations.OpenFile(FileNameLocation); } return(true); } } return(false); }