//
        // Creates a new log file and returns the path
        //
        private static string GenerateLogMessage(Review.Review.Properties properties, string reviewUrl, Logging logger)
        {
            // Get the temp file
            string logFile = Path.GetTempFileName();

            using (StreamWriter sw = new StreamWriter(logFile))
            {
                // Write our log to the file
                if (string.IsNullOrWhiteSpace(properties.Summary) == false)
                {
                    sw.WriteLine(properties.Summary + "\n");
                }

                if (string.IsNullOrWhiteSpace(properties.Description) == false)
                {
                    sw.WriteLine(properties.Description + "\n");
                }

                // Post the Jira state to this commit
                string jiraState = BuildJiraLogContent(properties.JiraId);
                sw.WriteLine(jiraState);

                // Post the review state to this commit
                sw.WriteLine(ReviewState_Tag, properties.ReviewLevel.GetSplitName(), reviewUrl == null ? string.Empty : reviewUrl.Replace("diff/", ""));

                // Add a tag identifying what it was generated by
                sw.WriteLine("\n* Commit log generated by '{0}' v{1}", "Reviewboard Integration Tools", RB_Tools.Shared.Utilities.Version.VersionNumber);
            }

            // Return the log file
            logger.Log("Log file generated - {0}", logFile);
            return(logFile);
        }
        //
        // Opens a new commit dialog with the given options
        //
        public static void OpenCommitDialog(Review.Review.Properties properties, string reviewUrl, Logging logger)
        {
            string logFile = GenerateLogMessage(properties, reviewUrl, logger);

            OpenTortoiseSVN(properties.Contents.Files, properties.Path, logFile, logger);
            AddLogMessageToJiraTicket(properties.JiraId, logFile, logger);
            // Clean up
            CleanUpTemporaryFiles(logFile, logger);
        }
Exemple #3
0
 // Constructor
 public ReviewRequestProperties(Review.Review.Properties reviewProperties, string workingCopy)
 {
     ReviewProperties = reviewProperties;
     WorkingCopy      = workingCopy;
 }
Exemple #4
0
        //
        // Starts a review
        //
        private void button_CreateReview_Click(object sender, EventArgs e)
        {
            // We need a sumary before we raise the review
            if (string.IsNullOrWhiteSpace(textBox_Summary.Text) == true)
            {
                MessageBox.Show(this, "You need to provide a summary before you can post a review", "Unable to post review", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Do we need a Jira ticket?
            if (Settings.Settings.Default.JiraRequired == true)
            {
                if (string.IsNullOrWhiteSpace(textBox_JiraId.Text) == true)
                {
                    MessageBox.Show(this, "You need to provide a Jira ticket before you can continue", "Unable to post review", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            // Only bother checking against the reviewboard server if we are doing a review
            RB_Tools.Shared.Review.Properties.Level reviewLevel = (RB_Tools.Shared.Review.Properties.Level)comboBox_ReviewLevel.SelectedIndex;
            if (reviewLevel == RB_Tools.Shared.Review.Properties.Level.FullReview)
            {
                string reviewboardServer = Names.Url[(int)Names.Type.Reviewboard];
                if (Credentials.Available(reviewboardServer) == false)
                {
                    m_logger.Log("Requesting Reviewboard credentials");

                    DialogResult dialogResult = MessageBox.Show(this, "You must be authenticated with the Reviewboard server before generating a review.\n\nDo you want to authenticate now?", "Authentication Error", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (dialogResult == DialogResult.Yes)
                    {
                        RB_Tools.Shared.Authentication.Targets.Reviewboard.Authenticate(m_logger);
                    }

                    // Check if we're still unauthenticated
                    if (Credentials.Available(reviewboardServer) == false)
                    {
                        m_logger.Log("Credentials still unavailable");
                        return;
                    }
                }
            }

            // Check Jira authentication if needed
            if (string.IsNullOrWhiteSpace(textBox_JiraId.Text) == false)
            {
                string jiraServer = Names.Url[(int)Names.Type.Jira];
                if (Credentials.Available(jiraServer) == false)
                {
                    m_logger.Log("Requesting Jira credentials");

                    DialogResult dialogResult = MessageBox.Show(this, "You must be authenticated with the Jira server before continuing.\n\nDo you want to authenticate now?", "Authentication Error", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (dialogResult == DialogResult.Yes)
                    {
                        RB_Tools.Shared.Authentication.Targets.Jira.Authenticate(m_logger);
                    }

                    // Check if we're still unauthenticated
                    if (Credentials.Available(jiraServer) == false)
                    {
                        m_logger.Log("Credentials still unavailable");
                        return;
                    }
                }
            }

            // Save the state of our review groups
            SaveSelectedReviewGroups();

            // Update our state
            UpdateCreateReviewDialogState(State.PostReview);

            // Do we need to keep our artifacts?
            if (checkBox_KeepArtifacts.Checked == true)
            {
                Utilities.Storage.KeepAssets(textBox_Summary.Text, m_logger);
            }
            Utilities.Storage.Keep(m_originalRequest, "Original File List.txt", false, m_logger);

            // Build up the list of review groups
            List <string> selectedReviewGroups = new List <string>();

            foreach (int thisIndex in checkedListBox_ReviewGroups.CheckedIndices)
            {
                Reviewboard.ReviewGroup thisGroup = m_reviewGroups[thisIndex];
                selectedReviewGroups.Add(thisGroup.InternalName);
            }

            // Build up the properties of this review
            Review.Review.Properties reviewProperties = new Review.Review.Properties(
                m_requestDirectory,

                m_reviewSource,

                textBox_ReviewId.Text,

                textBox_Summary.Text,
                textBox_Description.Text,
                textBox_Testing.Text,

                textBox_JiraId.Text.Trim().Replace(" ", ""),

                selectedReviewGroups,

                reviewLevel,
                checkBox_CopiesAsAdds.Checked
                );

            // Trigger the correct state depending on whether we are reviewing
            TriggerReviewRequest(reviewProperties);
        }
Exemple #5
0
        //
        // Runs the review request
        //
        private void TriggerReviewRequest(Review.Review.Properties reviewProperties)
        {
            m_logger.Log("Triggering review request");

            // Build up the background work
            BackgroundWorker updateThread = new BackgroundWorker();

            // Called when we need to trigger the request
            updateThread.DoWork += (object objectSender, DoWorkEventArgs args) =>
            {
                // Pull out the properties of the request
                ReviewRequestProperties thisRequest = args.Argument as ReviewRequestProperties;
                OutputRequestProperties(thisRequest);

                // Do we need to validate the Jira ticket?
                bool ticketValid = ValidateJiraTicket(thisRequest.ReviewProperties.JiraId);
                if (ticketValid == false)
                {
                    args.Result = new Reviewboard.ReviewRequestResult(null, "Unable to validate the given Jira ticket", thisRequest.ReviewProperties);
                    return;
                }

                // Carry out the review
                args.Result = RequestReview(thisRequest);
            };
            // Called when the thread is complete
            updateThread.RunWorkerCompleted += (object objectSender, RunWorkerCompletedEventArgs args) =>
            {
                // Check if we had an error
                if (args.Error != null)
                {
                    m_logger.Log("Error raised during review request - {0}", args.Error.Message);
                    string body = string.Format("Exception thrown when trying to raise a new review\n\nException: {0}\n\nDescription: {1}", args.Error.GetType().Name, args.Error.Message);

                    // Was it an authentication error?
                    bool authenticationRequired = false;
                    if (args.Error.Message.Contains("username or password was not correct") == true)
                    {
                        authenticationRequired = true;
                        body += "\n\nDo you want to attempt to reauthenticate with the server?";
                    }

                    // Show the options
                    MessageBoxButtons buttonTypes = (authenticationRequired == true ? MessageBoxButtons.YesNo : MessageBoxButtons.OK);
                    DialogResult      result      = MessageBox.Show(this, body, @"Unable to raise review", buttonTypes, MessageBoxIcon.Error);

                    // Continue?
                    if (result == DialogResult.Yes && authenticationRequired == true)
                    {
                        RB_Tools.Shared.Authentication.Targets.Reviewboard.Authenticate(m_logger);
                    }

                    OnReviewFinished(FinishReason.Error);
                }
                else
                {
                    // Pull out the results of the review
                    Reviewboard.ReviewRequestResult requestResult = args.Result as Reviewboard.ReviewRequestResult;

                    // If we don't have a review URL, we failed
                    if (string.IsNullOrWhiteSpace(requestResult.Error) == false)
                    {
                        m_logger.Log("Error raised during review request - {0}", requestResult.Error);

                        // Raise the error and we're done
                        MessageBox.Show(this, requestResult.Error, @"Unable to raise review", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        OnReviewFinished(FinishReason.Error);
                    }
                    else
                    {
                        if (requestResult.Properties.ReviewLevel == RB_Tools.Shared.Review.Properties.Level.FullReview)
                        {
                            m_logger.Log("Review posted successful - {0}", requestResult.Url);
                        }

                        // Open the browser, doing this manually so we can open on the diff
                        if (string.IsNullOrWhiteSpace(requestResult.Url) == false)
                        {
                            System.Diagnostics.Process.Start(requestResult.Url);
                        }

                        // If it's just a patch file, we don't need to do anything else
                        if (m_reviewSource.Source == Review.Review.Source.Patch)
                        {
                            m_logger.Log("Patch review completed, process finished");
                            OnReviewFinished(FinishReason.Success);
                        }
                        else
                        {
                            m_logger.Log("File review finished, moving onto next stage");

                            // Flag the actual review as done so we lose the path file
                            // and then it doesn't show up in TortoiseSVN
                            OnReviewFinished(FinishReason.Interim);
                            TriggerTortoiseRequest(requestResult);
                        }
                    }
                }
            };

            // Kick off the request
            ReviewRequestProperties requestProperties = new ReviewRequestProperties(reviewProperties, m_requestDirectory);

            updateThread.RunWorkerAsync(requestProperties);
        }
Exemple #6
0
 // Constructor
 public ReviewRequestResult(string reviewUrl, string reviewError, Review.Review.Properties reviewRequest)
 {
     Url        = reviewUrl;
     Error      = reviewError;
     Properties = reviewRequest;
 }
Exemple #7
0
        //
        // Raises a new review
        //
        public static ReviewRequestResult RequestReview(string workingDirectory, string server, string username, string password, Review.Review.Properties reviewProperties, Logging logger)
        {
            // We may not need to generate a review
            if (reviewProperties.ReviewLevel != RB_Tools.Shared.Review.Properties.Level.FullReview)
            {
                // No review needed so exit
                logger.Log("Ignoring review request as a full review was not requested");
                return(new ReviewRequestResult(string.Empty, string.Empty, reviewProperties));
            }

            // Read out the description and testing into a temp file
            string descriptionFile = GetFileWithContents(reviewProperties.Description, reviewProperties.Summary);
            string testingFile     = GetFileWithContents(reviewProperties.Testing, null);

            // Build up the review command
            string commandProperties = string.Format("--server {0} --summary \"{1}\" ", server, reviewProperties.Summary);

            if (string.IsNullOrWhiteSpace(descriptionFile) == false)
            {
                commandProperties += string.Format("--description-file \"{0}\" ", descriptionFile);
            }
            if (string.IsNullOrWhiteSpace(testingFile) == false)
            {
                commandProperties += string.Format("--testing-done-file \"{0}\" ", testingFile);
            }
            if (string.IsNullOrWhiteSpace(reviewProperties.JiraId) == false)
            {
                string formattedJiraIds = BuildJiraLinks(reviewProperties.JiraId);
                commandProperties += string.Format("--bugs-closed \"{0}\" ", formattedJiraIds);
            }

            // Options
            commandProperties += string.Format("--svn-show-copies-as-adds={0} ", reviewProperties.CopiesAsAdds == true ? "y":"n");

            // Build up the review groups
            if (reviewProperties.Groups.Count != 0)
            {
                string reviewGroups = reviewProperties.Groups[0];
                for (int i = 1; i < reviewProperties.Groups.Count; ++i)
                {
                    reviewGroups += "," + reviewProperties.Groups[i];
                }

                // Add the command
                commandProperties += string.Format("--target-groups \"{0}\" ", reviewGroups);
            }

            // Get the name of the branch we're on
            string branchUrl = Svn.GetBranch(workingDirectory);

            if (string.IsNullOrWhiteSpace(branchUrl) == false)
            {
                commandProperties += string.Format("--branch \"{0}\" ", branchUrl);
            }

            // Update an existing review?
            if (string.IsNullOrWhiteSpace(reviewProperties.ReviewId) == false)
            {
                commandProperties += string.Format("--review-request-id \"{0}\" ", reviewProperties.ReviewId);
            }

            // Pass through the patch file we generated or used
            commandProperties += string.Format("--diff-filename \"{0}\" ", reviewProperties.Contents.Patch);

            // Build up the command
            string commandOptions = string.Format(@"post {0}", commandProperties);
            string rbtPath        = RB_Tools.Shared.Targets.Reviewboard.Path();

            logger.Log("Requesting review");
            logger.Log("* Calling {0} {1}", rbtPath, commandOptions);

            // Run the process
            Process.Output output = Process.Start(workingDirectory, rbtPath, commandOptions);

            // Throw to return the error
            if (string.IsNullOrWhiteSpace(output.StdErr) == false)
            {
                logger.Log("Error raised when requesting review - {0}", output.StdErr);
                throw new ApplicationException(output.StdErr);
            }

            // Break up the results
            string[] outputLines = output.StdOut.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            // Pull out the link to the review (use the diff)
            string reviewUrl = string.Empty;

            if (outputLines.Length >= 3)
            {
                reviewUrl = outputLines[2];
            }

            // Review URL needs to reference the reviewboard server
            string reviewError = null;

            if (reviewUrl.ToLower().Contains(server.ToLower()) == false)
            {
                reviewError = output.StdOut;
            }

            // Lose the temp files if we have them
            CleanUpTemporaryFiles(descriptionFile, testingFile, logger);

            // Return the results
            return(new ReviewRequestResult(reviewUrl, reviewError, reviewProperties));
        }