private static void AssertExpectedErrorLog(BuildLog result, string expectedErrorLog)
 {
     result.AssertExpectedCapturedPropertyValue(TargetProperties.ErrorLog, expectedErrorLog);
     result.AssertExpectedCapturedPropertyValue(TargetProperties.RazorSonarCompileErrorLog, expectedErrorLog);
     result.AssertExpectedCapturedPropertyValue(TargetProperties.RazorCompilationErrorLog, expectedErrorLog);
 }
Exemplo n.º 2
0
        private async Task UploadLogLinesBlobAsync(string account, Build build, BuildLog log)
        {
            // we don't use FinishTime in the logs blob path to prevent duplicating logs when processing retries
            var blobPath   = $"{build.Project.Name}/{build.QueueTime:yyyy/MM/dd}/{build.Id}-{log.Id}.jsonl";
            var blobClient = this.buildLogLinesContainerClient.GetBlobClient(blobPath);

            if (await blobClient.ExistsAsync())
            {
                this.logger.LogInformation("Skipping existing log {LogId} for build {BuildId}", log.Id, build.Id);
                return;
            }

            var tempFile = Path.GetTempFileName();

            try
            {
                await using (var messagesWriter = new StreamWriter(File.OpenWrite(tempFile)))
                {
                    var logLines = await this.logProvider.GetLogLinesAsync(build, log.Id);

                    var lastTimeStamp = log.CreatedOn;

                    for (var lineNumber = 1; lineNumber <= logLines.Count; lineNumber++)
                    {
                        var line      = logLines[lineNumber - 1];
                        var match     = Regex.Match(line, @"^([^Z]{20,28}Z) (.*)$");
                        var timestamp = match.Success
                            ? DateTime.ParseExact(match.Groups[1].Value, TimeFormat, null,
                                                  System.Globalization.DateTimeStyles.AssumeUniversal).ToUniversalTime()
                            : lastTimeStamp;

                        var message = match.Success ? match.Groups[2].Value : line;

                        if (timestamp == null)
                        {
                            throw new Exception($"Error processing line {lineNumber}. No leading timestamp.");
                        }

                        await messagesWriter.WriteLineAsync(JsonConvert.SerializeObject(
                                                                new
                        {
                            OrganizationName  = account,
                            ProjectId         = build.Project.Id,
                            BuildId           = build.Id,
                            BuildDefinitionId = build.Definition.Id,
                            LogId             = log.Id,
                            LineNumber        = lineNumber,
                            Length            = message.Length,
                            Timestamp         = timestamp?.ToString(TimeFormat),
                            Message           = message,
                            EtlIngestDate     = DateTime.UtcNow.ToString(TimeFormat),
                        }, jsonSettings));

                        lastTimeStamp = timestamp;
                    }
                }

                await blobClient.UploadAsync(tempFile);
            }
            catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.Conflict)
            {
                this.logger.LogInformation("Ignoring exception from existing blob for log {LogId} for build {BuildId}", log.Id, build.Id);
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error processing log {LogId} for build {BuildId}", log.Id, build.Id);
                throw;
            }
            finally
            {
                if (File.Exists(tempFile))
                {
                    File.Delete(tempFile);
                }
            }
        }
Exemplo n.º 3
0
        private int Invoke(SourceTypes sourceType, string sourceData, string templateData, string targetPath, string buildLog, string sourceDataNetType, string sourceDataNetFunction)
        {
            PerformanceMetrics = new Dictionary <string, PerformanceMetric>();
            using (StartMetric("Whole Operation"))
            {
                try
                {
                    ContextObject.DefaultFormatter.AddFromType(typeof(DynamicLinq));
                    if (buildLog != null)
                    {
                        BuildLog = new StreamWriter(new FileStream(buildLog, FileMode.OpenOrCreate));
                    }

                    WriteHeader();
                    WriteLine("- Take '" + sourceType + "' from '" + sourceData + "', put it into '" + templateData + "' and store the result at '" + targetPath + "'");

                    if (!File.Exists(sourceData))
                    {
                        WriteErrorLine($"- The source file at '{sourceData}' does not exist");
                        CloseMessage();
                        return(-1);
                    }
                    if (!File.Exists(templateData))
                    {
                        WriteErrorLine($"- The template file at '{templateData}' does not exist");
                        CloseMessage();
                        return(-1);
                    }

                    object         data     = null;
                    IValueResolver resolver = null;
                    using (StartMetric("Get Data"))
                    {
                        try
                        {
                            switch (sourceType)
                            {
                            case SourceTypes.Json:
                                WriteLine($"- Load file '{sourceData}' and parse Json from it");
                                data     = JsonConvert.DeserializeObject(File.ReadAllText(sourceData));
                                resolver = new JsonNetValueResolver();
                                break;

                            case SourceTypes.Xml:
                                throw new NotSupportedException("The XML deserialisation is currently not supported");

                            case SourceTypes.NetFunction:
                                Console.WriteLine($"- Load Assembly '{sourceData}', search for type '{sourceDataNetType}'" +
                                                  $" and run public static object {sourceDataNetFunction}(); to obtain data");
                                if (sourceDataNetType == null)
                                {
                                    WriteErrorLine("- Expected the --source-data-net-type argument to contain an valid type");
                                    CloseMessage();
                                    return(-1);
                                }
                                if (sourceDataNetFunction == null)
                                {
                                    WriteErrorLine("- Expected the --source-data-net-function argument to contain an valid type");
                                    CloseMessage();
                                    return(-1);
                                }

                                var assembly = Assembly.LoadFrom(sourceData);
                                var type     = assembly.GetType(sourceDataNetType);

                                if (type == null)
                                {
                                    WriteErrorLine($"- The type '{sourceDataNetType}' was not found");
                                    CloseMessage();
                                    return(-1);
                                }

                                var method = type.GetMethods(BindingFlags.Public | BindingFlags.Static)
                                             .Where(e => e.ReturnType != typeof(void))
                                             .Where(e => e.GetParameters().Length == 0)
                                             .FirstOrDefault(e => e.Name.Equals(sourceDataNetFunction));

                                if (method == null)
                                {
                                    WriteErrorLine($"- The method '{sourceDataNetFunction}' was not found in type '{type}'. Expected to find a public static void Method without parameters.");
                                    CloseMessage();
                                    return(-1);
                                }

                                data = method.Invoke(null, null);
                                //File.WriteAllText("documentation.json", JsonConvert.SerializeObject(data));
                                break;

                            default:
                                throw new ArgumentOutOfRangeException(nameof(sourceType), sourceType, null);
                            }
                        }
                        catch (Exception e)
                        {
                            WriteErrorLine("- Error while loading the source file");
                            WriteErrorLine("----");
                            WriteErrorLine(e.ToString());
                            CloseMessage();
                            return(-1);
                        }
                    }

                    string template;
                    using (StartMetric("Get Template Content"))
                    {
                        WriteLine($"- Read all contents from file '{templateData}'");
                        template = File.ReadAllText(templateData);
                        WriteLine($"- Read '{template.Length}' chars from file");
                    }
                    using (var sourceFs = new FileStream(targetPath, FileMode.OpenOrCreate))
                    {
                        MorestachioDocumentInfo document;
                        WriteLine("- Parse the template");
                        using (StartMetric("Parse Template"))
                        {
                            document = Parser.ParseWithOptions(new ParserOptions(template, () => sourceFs, Encoding.UTF8, true)
                            {
                                Timeout       = TimeSpan.FromMinutes(1),
                                ValueResolver = resolver,
                            });
                        }

                        if (document.Errors.Any())
                        {
                            var sb = new StringBuilder();
                            sb.AppendLine("- Template Errors: ");
                            foreach (var morestachioError in document.Errors)
                            {
                                morestachioError.Format(sb);
                                sb.AppendLine();
                                sb.AppendLine("----");
                            }
                            WriteErrorLine(sb.ToString());
                            CloseMessage();
                            return(-1);
                        }

                        WriteLine("- Execute the parsed template");
                        using (StartMetric("Create Document"))
                        {
                            document.Create(data);
                        }

                        WriteLine("- Done");
                        Hr();
                    }
                }
                finally
                {
                    BuildLog?.Dispose();
                }
            }

            WriteLine("Performance Metrics: ");
            foreach (var performanceMetric in PerformanceMetrics)
            {
                WriteLine("\t Name: " + performanceMetric.Key);
                WriteLine("\t Time: " + performanceMetric.Value.Stopwatch.Elapsed.ToString("g"));
                Hr();
            }
            CloseMessage();
            return(1);
        }
Exemplo n.º 4
0
        public static void Inspect(BuildingContext context, TypeDef typeDef)
        {
            BuildLog.Info(Strings.LogInspectingTypeX, typeDef.Name);

            if (typeDef.IsInterface)
            {
                // Remove open generic interface
                if (typeDef.IsGenericTypeDefinition)
                {
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Base interfaces
                foreach (var @interface in context.ModelDef.Types.FindInterfaces(typeDef.UnderlyingType))
                {
                    context.DependencyGraph.AddEdge(typeDef, @interface, EdgeKind.Inheritance, EdgeWeight.High);
                }

                // Fields
                foreach (var field in typeDef.Fields)
                {
                    InspectField(context, typeDef, field, false);
                }
                return;
            }

            if (typeDef.IsStructure)
            {
                if (typeDef.UnderlyingType.IsGenericTypeDefinition)
                {
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Ancestor
                var parent = context.ModelDef.Types.FindAncestor(typeDef);
                if (parent != null)
                {
                    context.DependencyGraph.AddEdge(typeDef, parent, EdgeKind.Inheritance, EdgeWeight.High);
                }

                // Fields
                foreach (var field in typeDef.Fields)
                {
                    InspectField(context, typeDef, field, false);
                }
                return;
            }

            if (typeDef.IsEntity)
            {
                // Should we remove it or not?
                var hierarchyDef = context.ModelDef.FindHierarchy(typeDef);
                if (hierarchyDef == null)
                {
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Register closed generic types
                if (typeDef.IsGenericTypeDefinition)
                {
                    var allGenericConstraintsAreEntity = typeDef.UnderlyingType.GetGenericArguments()
                                                         .SelectMany(ga => ga.GetGenericParameterConstraints())
                                                         .All(constraintType => typeof(IEntity).IsAssignableFrom(constraintType));
                    // Skip automatic registration for open generic types whicn constraints are not IEntity
                    if (!allGenericConstraintsAreEntity)
                    {
                        return;
                    }

                    if (!typeDef.IsAbstract)
                    {
                        context.ModelInspectionResult.Register(new BuildGenericTypeInstancesAction(typeDef));
                    }
                    context.ModelInspectionResult.Register(new RemoveTypeAction(typeDef));
                    return;
                }

                // Ancestor
                var parent = context.ModelDef.Types.FindAncestor(typeDef);
                if (parent != null)
                {
                    context.DependencyGraph.AddEdge(typeDef, parent, EdgeKind.Inheritance, EdgeWeight.High);
                }

                // Interfaces
                foreach (var @interface in context.ModelDef.Types.FindInterfaces(typeDef.UnderlyingType))
                {
                    context.DependencyGraph.AddEdge(typeDef, @interface, EdgeKind.Implementation, EdgeWeight.High);
                }

                context.Validator.ValidateType(typeDef, hierarchyDef);
                // We should skip key fields inspection as they have been already inspected
                foreach (var field in typeDef.Fields.Where(f => !hierarchyDef.KeyFields.Any(kf => kf.Name == f.Name)))
                {
                    InspectField(context, typeDef, field, false);
                }
            }
        }
Exemplo n.º 5
0
 private static void AssertCodeAnalysisIsDisabled(BuildLog result, string expectedResolvedCodeAnalysisRuleset)
 {
     // Check the ruleset and error log are not set
     AssertExpectedErrorLog(result, string.Empty);
     AssertExpectedResolvedRuleset(result, expectedResolvedCodeAnalysisRuleset);
 }
        /// <summary>
        /// Checks that a SonarQubeSetting does not exist
        /// </summary>
        private static void AssertAnalysisSettingDoesNotExist(BuildLog actualResult, string settingName)
        {
            var matches = actualResult.GetCapturedItemValues(BuildTaskConstants.SettingItemName);

            matches.Should().BeEmpty("Not expected SonarQubeSetting with include value of '{0}' to exist. Actual occurrences: {1}", settingName, matches.Count());
        }
 private void AssertExpectedAnalyzers(BuildLog result, params string[] expected) =>
 AssertExpectedItemValuesExists(result, TargetProperties.AnalyzerItemType, expected);
 private static void AssertIsNotTestProject(BuildLog log)
 {
     log.GetPropertyAsBoolean(TargetProperties.SonarQubeTestProject).Should().BeFalse();
 }
 private static void AssertExpectedErrorLog(BuildLog result, string expectedErrorLog)
 {
     result.AssertExpectedCapturedPropertyValue(TargetProperties.ErrorLog, expectedErrorLog);
 }
 private static void AssertExpectedResolvedRuleset(BuildLog result, string expectedResolvedRuleset)
 {
     result.AssertExpectedCapturedPropertyValue(TargetProperties.ResolvedCodeAnalysisRuleset, expectedResolvedRuleset);
 }
Exemplo n.º 11
0
 private static void AssertIsNotTestProject(BuildLog log)
 {
     log.GetPropertyAsBoolean(TargetProperties.SonarQubeTestProject).Should().BeFalse();
     log.MessageLog.Should().Contain("categorized as MAIN project (production code).\n");
 }
Exemplo n.º 12
0
 private static void AssertIsTestProject(BuildLog log)
 {
     log.GetPropertyAsBoolean(TargetProperties.SonarQubeTestProject).Should().BeTrue();
     log.MessageLog.Should().Contain("categorized as TEST project (test code). This MSBuild project will not be analyzed.\n");
 }
Exemplo n.º 13
0
        private void buildButton_Click(object sender, EventArgs e)
        {
            targetFileDialog.FileName = fileName.Replace(".ps1", ".exe");
            if (targetFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            ApplicationData newApplicationData;

            if (exe64svc.Checked || exe32svc.Checked)
            {
                ServiceData newApp = new ServiceData();
                newApp.ServiceName = serviceName.Text;
                newApp.Description = serviceDescription.Text;
                newApp.DisplayName = serviceDisplayName.Text;
                newApplicationData = newApp;
            }
            else
            {
                newApplicationData = new ApplicationData();
            }

            newApplicationData.ApplicationName = Path.GetFileName(fileName);

            switch (frameworkVersion.Text)
            {
            case "Framework 2.0":
                newApplicationData.Framework = Framework.Framework20;;
                break;

            case "Framework 3.5":
                newApplicationData.Framework = Framework.Framework35;
                break;

            case "Framework 4.0":
                newApplicationData.Framework = Framework.Framework40;
                break;

            default:
                newApplicationData.Framework = Framework.Framework40;
                break;
            }

            newApplicationData.DebugBuild = !buildRelease.Checked;

            newApplicationData.HideConsole = hideConsole.Checked;

            if (iconImage.Tag != null)
            {
                newApplicationData.Icon = Properties.Resources.exe;
            }

            newApplicationData.LCID = ((ComboListItem <int>)regionalSettings.SelectedItem).Value;

            newApplicationData.Mode = threadingSTA.Checked ? ThreadMode.STA : ThreadMode.MTA;

            newApplicationData.Platform = (exe32.Checked || exe32svc.Checked) ? Platform.x86 : Platform.x64;

            newApplicationData.PublisherName = authorName.Text;

            newApplicationData.PublisherOrganization = authorCompany.Text;

            newApplicationData.Version = new Version(versionBox.Text.Replace(",", "."));

            newApplicationData.AdditionalFiles.AddRange(addFiles.Items.Cast <string>());

            if (signFile.Checked)
            {
                X509Store store = new X509Store(StoreName.My);
                store.Open(OpenFlags.ReadOnly);
                foreach (X509Certificate2 mCert in store.Certificates)
                {
                    if (mCert.Thumbprint == ((ComboListItem <string>)certificateSelector.SelectedItem).Value)
                    {
                        newApplicationData.SigningInformation = new SingingInformation()
                        {
                            Certificate     = mCert,
                            TimestampServer = timestampURL.Text
                        };
                    }
                }
            }


            using (BuildLog buildLog = new BuildLog(fileName, targetFileDialog.FileName, newApplicationData, verboseBuild.Checked))
            {
                buildLog.ShowDialog();
            }
        }
Exemplo n.º 14
0
 static Mod()
 {
     BuildLog.Info("Starting initialization.");
 }
 private void AssertExpectedAdditionalFiles(BuildLog result, params string[] expected) =>
 AssertExpectedItemValuesExists(result, TargetProperties.AdditionalFilesItemType, expected);
Exemplo n.º 16
0
        private void BuildClassTableIndexes(TypeInfo type)
        {
            if (type.Indexes.Count > 0)
            {
                return;
            }
            if (type.IsStructure)
            {
                return;
            }

            var root       = type.Hierarchy.Root;
            var typeDef    = context.ModelDef.Types[type.UnderlyingType];
            var ancestors  = type.GetAncestors().ToList();
            var interfaces = type.GetInterfaces();

            // Building declared indexes both secondary and primary (for root of the hierarchy only)
            foreach (var indexDescriptor in typeDef.Indexes)
            {
                // Skip indef building for inherited fields
                var hasInheritedFields = indexDescriptor.KeyFields
                                         .Select(kvp => type.Fields[kvp.Key])
                                         .Any(f => f.IsInherited);
                if (hasInheritedFields)
                {
                    continue;
                }
                var declaredIndex = BuildIndex(type, indexDescriptor, false);

                type.Indexes.Add(declaredIndex);
                context.Model.RealIndexes.Add(declaredIndex);
            }

            // Building primary index for non root entities
            var parent = type.GetAncestor();

            if (parent != null)
            {
                var parentPrimaryIndex = parent.Indexes.FindFirst(IndexAttributes.Primary | IndexAttributes.Real);
                var inheritedIndex     = BuildInheritedIndex(type, parentPrimaryIndex, false);

                type.Indexes.Add(inheritedIndex);
                context.Model.RealIndexes.Add(inheritedIndex);
            }

            // Building inherited from interfaces indexes
            foreach (var @interface in interfaces)
            {
                foreach (var interfaceIndex in @interface.Indexes.Find(IndexAttributes.Primary, MatchType.None))
                {
                    if (interfaceIndex.DeclaringIndex != interfaceIndex &&
                        parent != null &&
                        parent.Indexes.Any(i => i.DeclaringIndex == interfaceIndex))
                    {
                        continue;
                    }
                    if (type.Indexes.Any(i => i.DeclaringIndex == interfaceIndex))
                    {
                        continue;
                    }
                    var index = BuildInheritedIndex(type, interfaceIndex, false);
                    if (IndexBuiltOverInheritedFields(index))
                    {
                        BuildLog.Warning(string.Format(Strings.ExUnableToBuildIndexXBecauseItWasBuiltOverInheritedFields, index.Name));
                    }
                    else
                    {
                        type.Indexes.Add(index);
                        context.Model.RealIndexes.Add(index);
                    }
                }
            }

            // Build typed indexes
            if (type == root)
            {
                foreach (var realIndex in type.Indexes.Find(IndexAttributes.Real))
                {
                    if (!untypedIndexes.Contains(realIndex))
                    {
                        continue;
                    }
                    var typedIndex = BuildTypedIndex(type, realIndex);
                    type.Indexes.Add(typedIndex);
                }
            }

            // Build indexes for descendants
            foreach (var descendant in type.GetDescendants())
            {
                BuildClassTableIndexes(descendant);
            }

            // Import inherited indexes
            var primaryIndex = type.Indexes.FindFirst(IndexAttributes.Primary | IndexAttributes.Real);

            if (untypedIndexes.Contains(primaryIndex) && primaryIndex.ReflectedType == root)
            {
                primaryIndex = type.Indexes.Single(i => i.DeclaringIndex == primaryIndex.DeclaringIndex && i.IsTyped);
            }
            var filterByTypes = type.GetDescendants(true).AddOne(type).ToList();

            // Build virtual primary index
            if (ancestors.Count > 0)
            {
                var baseIndexes = new Stack <IndexInfo>();
                foreach (var ancestor in ancestors.Where(t => t.Fields.Any(f => !f.IsPrimaryKey && !f.IsTypeId && f.IsDeclared)))
                {
                    var ancestorIndex = ancestor.Indexes.Single(i => i.IsPrimary && !i.IsVirtual);
                    if (untypedIndexes.Contains(ancestorIndex) && ancestorIndex.ReflectedType == root)
                    {
                        ancestorIndex = ancestor.Indexes.Single(i => i.DeclaringIndex == ancestorIndex.DeclaringIndex && i.IsTyped);
                    }
                    if (ancestorIndex.ValueColumns.Count > 0)
                    {
                        baseIndexes.Push(ancestorIndex);
                    }
                }
                if (baseIndexes.Count > 0)
                {
                    if (primaryIndex.ValueColumns.Count > 0 && type.Fields.Any(f => !f.IsPrimaryKey && !f.IsTypeId && f.IsDeclared))
                    {
                        baseIndexes.Push(primaryIndex);
                    }
                    else
                    {
                        var ancestorIndex = baseIndexes.Pop();
                        var filteredIndex = BuildFilterIndex(type, ancestorIndex, filterByTypes);
                        baseIndexes.Push(filteredIndex);
                    }
                    var virtualPrimaryIndex = baseIndexes.Count == 1
            ? baseIndexes.Pop()
            : BuildJoinIndex(type, baseIndexes);
                    type.Indexes.Add(virtualPrimaryIndex);
                }
            }

            // Build virtual secondary index
            foreach (var ancestorIndex in ancestors.SelectMany(ancestor => ancestor.Indexes.Find(IndexAttributes.Primary | IndexAttributes.Virtual, MatchType.None)))
            {
                if (ancestorIndex.DeclaringIndex != ancestorIndex)
                {
                    continue;
                }
                var ancestorType  = ancestorIndex.ReflectedType;
                var indexToFilter = untypedIndexes.Contains(ancestorIndex) && ancestorIndex.ReflectedType == root
          ? ancestorType.Indexes.Single(i => i.DeclaringIndex == ancestorIndex.DeclaringIndex && i.IsTyped)
          : ancestorIndex;

                var virtualIndex = BuildFilterIndex(type, ancestorIndex, filterByTypes);
                type.Indexes.Add(virtualIndex);
            }
        }
 /// <summary>
 /// Checks that no analysis warnings will be treated as errors nor will they be ignored
 /// </summary>
 private static void AssertWarningsAreNotTreatedAsErrorsNorIgnored(BuildLog actualResult)
 {
     actualResult.AssertExpectedCapturedPropertyValue(TargetProperties.TreatWarningsAsErrors, "false");
     actualResult.AssertExpectedCapturedPropertyValue(TargetProperties.WarningsAsErrors, "");
     actualResult.AssertExpectedCapturedPropertyValue(TargetProperties.WarningLevel, "4");
 }
 private static void AssertProjectIsNotExcluded(BuildLog log)
 {
     log.GetPropertyAsBoolean(TargetProperties.SonarQubeExcludeMetadata).Should().BeFalse();
 }
Exemplo n.º 19
0
        /// <summary>
        /// Default implementation of generating Asset Bundles using the Scriptable Build Pipeline.
        /// </summary>
        /// <param name="parameters">Set of parameters used for building asset bundles.</param>
        /// <param name="content">Set of content and explicit asset bundle layout to build.</param>
        /// <param name="result">Results from building the content and explicit asset bundle layout.</param>
        /// <param name="taskList">Custom task list for building asset bundles.</param>
        /// <param name="contextObjects">Additional context objects to make available to the build.</param>
        /// <returns>Return code with status information about success or failure causes.</returns>
        public static ReturnCode BuildAssetBundles(IBundleBuildParameters parameters, IBundleBuildContent content, out IBundleBuildResults result, IList <IBuildTask> taskList, params IContextObject[] contextObjects)
        {
            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (parameters == null)
            {
                result = null;
                BuildLogger.LogException(new ArgumentNullException("parameters"));
                return(ReturnCode.Exception);
            }

            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (taskList.IsNullOrEmpty())
            {
                result = null;
                BuildLogger.LogException(new ArgumentException("Argument cannot be null or empty.", "taskList"));
                return(ReturnCode.Exception);
            }

            // Don't run if there are unsaved changes
            if (ValidationMethods.HasDirtyScenes())
            {
                result = null;
                return(ReturnCode.UnsavedChanges);
            }

            AssetDatabase.SaveAssets();

            ReturnCode exitCode;

            result = new BundleBuildResults();
            BuildCacheUtility.ClearCacheHashes();
            using (var interfacesWrapper = new BuildInterfacesWrapper())
#if !CI_TESTRUNNER_PROJECT
                using (new SceneStateCleanup())
                    using (var progressTracker = new ProgressTracker())
#else
                using (var progressTracker = new ProgressLoggingTracker())
#endif
                        using (var buildCache = new BuildCache(parameters.CacheServerHost, parameters.CacheServerPort))
                        {
                            Directory.CreateDirectory(parameters.TempOutputFolder);

                            BuildContext buildContext;
                            BuildLog     buildLog = null;

                            try
                            {
                                buildContext = new BuildContext(contextObjects);
                                buildContext.SetContextObject(parameters);
                                buildContext.SetContextObject(content);
                                buildContext.SetContextObject(result);
                                buildContext.SetContextObject(interfacesWrapper);
                                buildContext.SetContextObject(progressTracker);
                                buildContext.SetContextObject(buildCache);
                                // If IDeterministicIdentifiers was passed in with contextObjects, don't add the default
                                if (!buildContext.ContainsContextObject(typeof(IDeterministicIdentifiers)))
                                {
                                    buildContext.SetContextObject(new Unity5PackedIdentifiers());
                                }
                                buildContext.SetContextObject(new BuildDependencyData());
                                buildContext.SetContextObject(new BundleWriteData());
                                buildContext.SetContextObject(BuildCallbacks);

                                IBuildLogger logger;
                                if (!buildContext.TryGetContextObject <IBuildLogger>(out logger))
                                {
                                    logger = buildLog = new BuildLog();
                                    buildContext.SetContextObject(buildLog);
                                }
                                buildCache.SetBuildLogger(logger);
                            }
                            catch (Exception e)
                            {
                                // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
                                result = null;
                                BuildLogger.LogException(e);
                                return(ReturnCode.Exception);
                            }

                            exitCode = BuildTasksRunner.Validate(taskList, buildContext);
                            if (exitCode >= ReturnCode.Success)
#if SBP_PROFILER_ENABLE
                            { exitCode = BuildTasksRunner.RunProfiled(taskList, buildContext); }
#else
                            { exitCode = BuildTasksRunner.Run(taskList, buildContext); }
#endif

                            if (Directory.Exists(parameters.TempOutputFolder))
                            {
                                Directory.Delete(parameters.TempOutputFolder, true);
                            }

                            if (buildLog != null)
                            {
                                string buildLogPath = parameters.GetOutputFilePathForIdentifier("buildlog.txt");
                                Directory.CreateDirectory(Path.GetDirectoryName(buildLogPath));
                                File.WriteAllText(buildLogPath, buildLog.FormatAsText());
                                File.WriteAllText(parameters.GetOutputFilePathForIdentifier("buildlogtep.json"), buildLog.FormatAsTraceEventProfiler());
                            }
                        }


            long maximumCacheSize = ScriptableBuildPipeline.maximumCacheSize * 1073741824L; // gigabytes to bytes
            ThreadPool.QueueUserWorkItem(PruneCache, maximumCacheSize);
            return(exitCode);
        }