예제 #1
0
        /// <summary>
        /// Request the active build process to update.
        /// Returns <see langword="true"/> to indicate that it must be called again, otherwise <see langword="false"/> to indicate that the build has completed.
        /// </summary>
        /// <returns><see langword="true"/> if <see cref="Update"/> must be called again, otherwise <see langword="false"/>.</returns>
        public bool Update()
        {
            if (IsCompleted)
            {
                return(false);
            }

            if (!m_Timer.IsRunning)
            {
                m_Timer.Restart();
            }

            try
            {
                Result = m_OnBuild(m_Context);
            }
            catch (Exception exception)
            {
                Result = m_Context.Failure(exception);
            }

            if (!IsCompleted)
            {
                return(true);
            }

            m_Timer.Stop();
            Result.Duration = m_Timer.Elapsed;
            BuildArtifacts.Store(Result, m_Context.Values.OfType <IBuildArtifact>().ToArray());
            return(false);
        }
예제 #2
0
        /// <summary>
        /// Request the active build process to update.
        /// Returns <see langword="true"/> to indicate that it must be called again, otherwise <see langword="false"/> to indicate that the build has completed.
        /// </summary>
        /// <returns><see langword="true"/> if <see cref="Update"/> must be called again, otherwise <see langword="false"/>.</returns>
        public bool Update()
        {
            if (IsCompleted)
            {
                return(false);
            }

            if (!m_Timer.IsRunning)
            {
                m_Timer.Restart();
                m_StartTime = DateTime.Now;
            }

            try
            {
                Result = m_OnBuild(m_Context);
            }
            catch (Exception exception)
            {
                Result = m_Context.Failure(exception);
            }

            if (!IsCompleted)
            {
                return(true);
            }

            m_Timer.Stop();
            Result.StartTime = m_StartTime;
            Result.Duration  = m_Timer.Elapsed;
            BuildArtifacts.Serialize(Result, m_Context.GetAllBuildArtifacts().ToArray());
            return(false);
        }
        /// <summary>
        /// Run all enabled build steps and cleanup.
        /// </summary>
        /// <param name="context">The current build context.</param>
        /// <returns>A build result indicating if successful or not.</returns>
        public BuildResult Run(BuildContext context)
        {
            var results = new List <BuildResult>();
            var title   = context.BuildProgress?.Title ?? string.Empty;

            // Setup build steps list
            var cleanupSteps = new Stack <BuildStepBase>();
            var enabledSteps = m_BuildSteps.Where(step => step.IsEnabled(context)).ToArray();

            // Run build steps and stop on first failure of any kind
            for (var i = 0; i < enabledSteps.Length; ++i)
            {
                var step = enabledSteps[i];

                // Update build progress
                var cancelled = context.BuildProgress?.Update($"{title} (Step {i + 1} of {enabledSteps.Length})", step.Description + "...", (float)i / enabledSteps.Length) ?? false;
                if (cancelled)
                {
                    results.Add(context.Failure($"{title} was cancelled."));
                    break;
                }

                // Add step to cleanup stack only if it overrides implementation
                if (step.GetType().GetMethod(nameof(BuildStepBase.Cleanup)).DeclaringType != typeof(BuildStepBase))
                {
                    cleanupSteps.Push(step);
                }

                // Run step
                try
                {
                    results.Add(step.Run(context));
                    if (results.Last().Failed)
                    {
                        break;
                    }
                }
                catch (Exception exception)
                {
                    results.Add(context.Failure(exception));
                    break;
                }
            }

            // Execute cleanup (even if there are failures):
            // 1) in opposite order of steps that ran.
            // 2) can't be cancelled; cleanup must run.
            foreach (var step in cleanupSteps)
            {
                context.BuildProgress?.Update($"{title} (Cleanup)", step.Description + "...", 1.0F);
                try
                {
                    results.Add(step.Cleanup(context));
                }
                catch (Exception exception)
                {
                    results.Add(context.Failure(exception));
                }
            }

            // Return the first failed result if any
            var failure = results.FirstOrDefault(result => result.Failed);

            return(failure != null ? failure : context.Success());
        }