Beispiel #1
0
        /// <summary>
        /// Outputs an indented message to the build log if its priority is 
        /// greather than or equal to the <see cref="Threshold" /> of the 
        /// logger.
        /// </summary>
        /// <param name="e">The event to output.</param>
        /// <param name="indentationLength">TODO</param>
        private void OutputMessage(BuildEventArgs e, int indentationLength)
        {
            if (e.MessageLevel >= Threshold) {
                string txt = e.Message;

                // beautify the message a bit
                txt = txt.Replace("\t", " "); // replace tabs with spaces
                txt = txt.Replace("\r", ""); // get rid of carriage returns

                // split the message by lines - the separator is "\n" since we've eliminated
                // \r characters
                string[] lines = txt.Split('\n');
                string label = String.Empty;

                if (e.Task != null && !EmacsMode) {
                    label = "[" + e.Task.Name + "] ";
                    label = label.PadLeft(e.Project.IndentationSize);
                }

                if (indentationLength > 0) {
                    label = new String(' ', indentationLength) + label;
                }

                foreach (string line in lines) {
                    StringBuilder sb = new StringBuilder();
                    sb.Append(label);
                    sb.Append(line);

                    string indentedMessage = sb.ToString();

                    // output the message to the console
                    Console.Out.WriteLine(indentedMessage);

                    // if an OutputWriter was set, write the message to it
                    if (OutputWriter != null) {
                        OutputWriter.WriteLine(indentedMessage);
                    }

                    Log(indentedMessage);
                }
            }
        }
Beispiel #2
0
 private static BuildEventArgs CreateBuildEvent(Level messageLevel, string message)
 {
     BuildEventArgs buildEvent = new BuildEventArgs();
     buildEvent.MessageLevel = messageLevel;
     buildEvent.Message = message;
     return buildEvent;
 }
Beispiel #3
0
        /// <summary>
        /// Outputs an indented message to the build log if its priority is 
        /// greather than or equal to the <see cref="Threshold" /> of the 
        /// logger.
        /// </summary>
        /// <param name="e">The event to output.</param>
        private void OutputMessage(BuildEventArgs e)
        {
            int indentationLength = 0;

            if (e.Project != null) {
                indentationLength = e.Project.IndentationLevel * e.Project.IndentationSize;
            }

            OutputMessage(e, indentationLength);
        }
Beispiel #4
0
 /// <summary>
 /// Signals that a task has finished.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">A <see cref="BuildEventArgs" /> object that contains the event data.</param>
 /// <remarks>
 /// This event will still be fired if an error occurred during the build.
 /// </remarks>
 public virtual void TaskFinished(object sender, BuildEventArgs e)
 {
 }
Beispiel #5
0
 /// <summary>
 /// Signals that a task has started.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">A <see cref="BuildEventArgs" /> object that contains the event data.</param>
 public virtual void TaskStarted(object sender, BuildEventArgs e)
 {
 }
Beispiel #6
0
        /// <summary>
        /// Signals that a message has been logged.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">A <see cref="BuildEventArgs" /> object that contains the event data.</param>
        /// <remarks>
        /// Only messages with a priority higher or equal to the threshold of 
        /// the logger will actually be output in the build log.
        /// </remarks>
        public virtual void MessageLogged(object sender, BuildEventArgs e)
        {
            if (_buildReports.Count > 0) {
                if (e.MessageLevel == Level.Error) {
                    BuildReport report = (BuildReport) _buildReports.Peek();
                    report.Errors++;
                } else if (e.MessageLevel == Level.Warning) {
                    BuildReport report = (BuildReport) _buildReports.Peek();
                    report.Warnings++;
                }
            }

            // output the message
            OutputMessage(e);
        }
Beispiel #7
0
        /// <summary>
        /// Signals that a target has started.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">A <see cref="BuildEventArgs" /> object that contains the event data.</param>
        public virtual void TargetStarted(object sender, BuildEventArgs e)
        {
            int indentationLevel = 0;

            if (e.Project != null) {
                indentationLevel = e.Project.IndentationLevel * e.Project.IndentationSize;
            }

            if (e.Target != null) {
                OutputMessage(Level.Info, string.Empty, indentationLevel);
                OutputMessage(
                    Level.Info,
                    string.Format(CultureInfo.InvariantCulture, "{0}:", e.Target.Name),
                    indentationLevel);
                OutputMessage(Level.Info, string.Empty, indentationLevel);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Signals that the last target has finished.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">A <see cref="BuildEventArgs" /> object that contains the event data.</param>
        /// <remarks>
        /// This event will still be fired if an error occurred during the build.
        /// </remarks>
        public virtual void BuildFinished(object sender, BuildEventArgs e)
        {
            Exception error = e.Exception;
            int indentationLevel = 0;

            if (e.Project != null) {
                indentationLevel = e.Project.IndentationLevel * e.Project.IndentationSize;
            }

            BuildReport report = (BuildReport) _buildReports.Pop();

            if (error == null) {
                OutputMessage(Level.Info, string.Empty, indentationLevel);
                if (report.Errors == 0 && report.Warnings == 0) {
                    OutputMessage(Level.Info, "BUILD SUCCEEDED", indentationLevel);
                } else {
                    OutputMessage(Level.Info, string.Format(CultureInfo.InvariantCulture,
                        ResourceUtils.GetString("String_BuildSucceeded"),
                        report.Errors, report.Warnings), indentationLevel);
                }
                OutputMessage(Level.Info, string.Empty, indentationLevel);
            } else {
                OutputMessage(Level.Error, string.Empty, indentationLevel);
                if (report.Errors == 0 && report.Warnings == 0) {
                    OutputMessage(Level.Error, "BUILD FAILED", indentationLevel);
                } else {
                    OutputMessage(Level.Info, string.Format(CultureInfo.InvariantCulture,
                        ResourceUtils.GetString("String_BuildFailed"),
                        report.Errors, report.Warnings), indentationLevel);
                }
                OutputMessage(Level.Error, string.Empty, indentationLevel);

                if (error is BuildException) {
                    if (Threshold <= Level.Verbose) {
                        OutputMessage(Level.Error, error.ToString(), indentationLevel);
                    } else {
                        if (error.Message != null) {
                            OutputMessage(Level.Error, error.Message, indentationLevel);
                        }

                        // output nested exceptions
                        Exception nestedException = error.InnerException;
                        int exceptionIndentationLevel = indentationLevel;
                        int indentShift = 4; //e.Project.IndentationSize;
                        while (nestedException != null && !StringUtils.IsNullOrEmpty(nestedException.Message)) {
                            exceptionIndentationLevel += indentShift;
                            OutputMessage(Level.Error, nestedException.Message, exceptionIndentationLevel);
                            nestedException = nestedException.InnerException;
                        }
                    }
                } else {
                    OutputMessage(Level.Error, "INTERNAL ERROR", indentationLevel);
                    OutputMessage(Level.Error, string.Empty, indentationLevel);
                    OutputMessage(Level.Error, error.ToString(), indentationLevel);
                    OutputMessage(Level.Error, string.Empty, indentationLevel);
                    OutputMessage(Level.Error, "Please send bug report to [email protected].", indentationLevel);
                }

                OutputMessage(Level.Error, string.Empty, indentationLevel);
            }

            // output total build time
            TimeSpan buildTime = DateTime.Now - report.StartTime;
            OutputMessage(Level.Info, string.Format(CultureInfo.InvariantCulture,
                ResourceUtils.GetString("String_TotalTime") + Environment.NewLine,
                Math.Round(buildTime.TotalSeconds, 1)), indentationLevel);

            // make sure all messages are written to the underlying storage
            Flush();
        }
Beispiel #9
0
 /// <summary>
 /// Signals that a build has started.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">A <see cref="BuildEventArgs" /> object that contains the event data.</param>
 /// <remarks>
 /// This event is fired before any targets have started.
 /// </remarks>
 public virtual void BuildStarted(object sender, BuildEventArgs e)
 {
     _buildReports.Push(new BuildReport(DateTime.Now));
 }
Beispiel #10
0
 /// <summary>
 /// Dispatches a <see cref="TargetStarted" /> event to the build listeners 
 /// for this <see cref="Project" />.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">A <see cref="BuildEventArgs" /> that contains the event data.</param>
 public void OnTargetStarted(object sender, BuildEventArgs e)
 {
     if (TargetStarted != null) {
         TargetStarted(sender, e);
     }
 }
Beispiel #11
0
 /// <summary>
 /// Dispatches the <see cref="TaskFinished" /> event to the build listeners 
 /// for this <see cref="Project" />.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">A <see cref="BuildEventArgs" /> that contains the event data.</param>
 public void OnTaskFinished(object sender, BuildEventArgs e)
 {
     if (TaskFinished != null) {
         TaskFinished(sender, e);
     }
 }
Beispiel #12
0
 /// <summary>
 /// Dispatches a <see cref="MessageLogged" /> event to the build listeners 
 /// for this <see cref="Project" />.
 /// </summary>
 /// <param name="e">A <see cref="BuildEventArgs" /> that contains the event data.</param>
 public void OnMessageLogged(BuildEventArgs e)
 {
     if (MessageLogged != null) {
         MessageLogged(this, e);
     }
 }
Beispiel #13
0
 /// <summary>
 /// Dispatches a <see cref="BuildStarted" /> event to the build listeners 
 /// for this <see cref="Project" />.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">A <see cref="BuildEventArgs" /> that contains the event data.</param>
 public void OnBuildStarted(object sender, BuildEventArgs e)
 {
     if (BuildStarted != null) {
         BuildStarted(sender, e);
     }
 }
Beispiel #14
0
        /// <summary>
        /// Writes a <see cref="Target" /> level message to the build log with 
        /// the given <see cref="Level" />.
        /// </summary>
        /// <param name="target">The <see cref="Target" /> from which the message orignated.</param>
        /// <param name="messageLevel">The level to log at.</param>
        /// <param name="message">The message to log.</param>
        public void Log(Target target, Level messageLevel, string message)
        {
            BuildEventArgs eventArgs = new BuildEventArgs(target);

            eventArgs.Message = message;
            eventArgs.MessageLevel = messageLevel;
            OnMessageLogged(eventArgs);
        }
Beispiel #15
0
        /// <summary>
        /// Writes a <see cref="Project" /> level formatted message to the build 
        /// log with the given <see cref="Level" />.
        /// </summary>
        /// <param name="messageLevel">The <see cref="Level" /> to log at.</param>
        /// <param name="message">The message to log, containing zero or more format items.</param>
        /// <param name="args">An <see cref="object" /> array containing zero or more objects to format.</param>
        public void Log(Level messageLevel, string message, params object[] args)
        {
            BuildEventArgs eventArgs = new BuildEventArgs(this);

            eventArgs.Message = string.Format(CultureInfo.InvariantCulture, message, args);
            eventArgs.MessageLevel = messageLevel;
            OnMessageLogged(eventArgs);
        }
Beispiel #16
0
        /// <summary>
        /// Executes the default target and wraps in error handling and time 
        /// stamping.
        /// </summary>
        /// <returns>
        /// <see langword="true" /> if the build was successful; otherwise, 
        /// <see langword="false" />.
        /// </returns>
        public bool Run()
        {
            Exception error = null;

            try {
                OnBuildStarted(this, new BuildEventArgs(this));

                // output build file that we're running
                Log(Level.Info, "Buildfile: {0}", BuildFileUri);

                // output current target framework in build log
                Log(Level.Info, "Target framework: {0}", TargetFramework != null
                    ? TargetFramework.Description : "None");

                // write verbose project information after Initialize to make
                // sure properties are correctly initialized
                Log(Level.Verbose, "Base Directory: {0}.", BaseDirectory);

                // execute the project
                Execute();

                // signal build success
                return true;
            } catch (BuildException e) {
                // store exception in error variable in order to include it
                // in the BuildFinished event.
                error = e;

                // log exception details to log4net
                logger.Error("Build failed.", e);

                // signal build failure
                return false;
            } catch (Exception e) {
                // store exception in error variable in order to include it
                // in the BuildFinished event.
                error = e;

                // log exception details to log4net
                logger.Fatal("Build failed.", e);

                // signal build failure
                return false;
            } finally {
                string endTarget;

                if (error == null) {
                    endTarget = Properties[CIScriptPropertyOnSuccess];
                } else {
                    endTarget = Properties[CIScriptPropertyOnFailure];
                }

                // TO-DO : remove this after release of CIScript 0.8.4 or so
                string deprecatedFailureTarget = Properties["ciscript.failure"];

                if (!StringUtils.IsNullOrEmpty(deprecatedFailureTarget)) {
                    Log(Level.Warning, "The 'ciscript.failure' property has been deprecated." +
                        " You should use '{0}' to designate the target that should be" +
                        " executed when the build fails." + Environment.NewLine,
                        Project.CIScriptPropertyOnFailure);
                    if (error != null) {
                        Execute(deprecatedFailureTarget);
                    }
                }

                if (!StringUtils.IsNullOrEmpty(endTarget)) {
                    // executing the target identified by the 'ciscript.onsuccess'
                    // or 'ciscript.onfailure' properties should not affect the
                    // build outcome
                    CallTask callTask = new CallTask();
                    callTask.Parent = this;
                    callTask.Project = this;
                    callTask.NamespaceManager = NamespaceManager;
                    callTask.Verbose = Verbose;
                    callTask.FailOnError = false;
                    callTask.TargetName = endTarget;
                    callTask.Execute();
                }

                // fire BuildFinished event with details of build outcome
                BuildEventArgs buildFinishedArgs = new BuildEventArgs(this);

                buildFinishedArgs.Exception = error;
                OnBuildFinished(this, buildFinishedArgs);
            }
        }