WriteResXFile( string projectPath) { if (0 == Graph.Instance.Packages.Count()) { throw new Exception("Package has not been specified. Run 'bam' from the package directory."); } var masterPackage = Graph.Instance.MasterPackage; var projectDirectory = System.IO.Path.GetDirectoryName(projectPath); IOWrapper.CreateDirectoryIfNotExists(projectDirectory); var resourceFilePathName = System.IO.Path.Combine(projectDirectory, "PackageInfoResources.resx"); var resourceFile = new System.Xml.XmlDocument(); var root = resourceFile.CreateElement("root"); resourceFile.AppendChild(root); AddResHeader(resourceFile, "resmimetype", "text/microsoft-resx", root); AddResHeader(resourceFile, "version", "2.0", root); // TODO: this looks like the System.Windows.Forms.dll assembly AddResHeader(resourceFile, "reader", "System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", root); AddResHeader(resourceFile, "writer", "System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", root); AddData(resourceFile, "BamInstallDir", Core.Graph.Instance.ProcessState.ExecutableDirectory, root); // TODO: could be Core.Graph.Instance.ProcessState.WorkingDirectory? AddData(resourceFile, "WorkingDir", masterPackage.GetPackageDirectory(), root); var xmlWriterSettings = new System.Xml.XmlWriterSettings(); xmlWriterSettings.Indent = true; xmlWriterSettings.CloseOutput = true; xmlWriterSettings.OmitXmlDeclaration = true; using (var xmlWriter = System.Xml.XmlWriter.Create(resourceFilePathName, xmlWriterSettings)) { resourceFile.WriteTo(xmlWriter); xmlWriter.WriteWhitespace(xmlWriterSettings.NewLineChars); } return(resourceFilePathName); }
Run() { Log.Detail("Running build..."); // TODO: should the rank collections be sorted, so that modules with fewest dependencies are first? var graph = Graph.Instance; var metaDataType = graph.BuildModeMetaData.GetType(); var useEvaluation = CheckIfModulesNeedRebuilding(metaDataType); var explainRebuild = CommandLineProcessor.Evaluate(new Options.ExplainBuildReason()); var immediateOutput = CommandLineProcessor.Evaluate(new Options.ImmediateOutput()); ExecutePreBuild(metaDataType); // necessary if built with debug symbols IOWrapper.CreateDirectoryIfNotExists(graph.BuildRoot); var threadCount = CommandLineProcessor.Evaluate(new Options.MultiThreaded()); if (0 == threadCount) { threadCount = System.Environment.ProcessorCount; } System.Exception abortException = null; if (threadCount > 1) { using (var cancellationSource = new System.Threading.CancellationTokenSource()) { var cancellationToken = cancellationSource.Token; // LongRunning is absolutely necessary in order to achieve paralleism var creationOpts = System.Threading.Tasks.TaskCreationOptions.LongRunning; var continuationOpts = System.Threading.Tasks.TaskContinuationOptions.LongRunning; var scheduler = new LimitedConcurrencyLevelTaskScheduler(threadCount); var factory = new System.Threading.Tasks.TaskFactory( cancellationToken, creationOpts, continuationOpts, scheduler); var tasks = new Array <System.Threading.Tasks.Task>(); foreach (var rank in graph.Reverse()) { foreach (var module in rank) { var context = new ExecutionContext(useEvaluation, explainRebuild, immediateOutput); var task = factory.StartNew(() => { if (cancellationToken.IsCancellationRequested) { return; } var depTasks = new Array <System.Threading.Tasks.Task>(); foreach (var dep in module.Dependents) { if (null == dep.ExecutionTask) { continue; } depTasks.Add(dep.ExecutionTask); } foreach (var dep in module.Requirements) { if (null == dep.ExecutionTask) { continue; } depTasks.Add(dep.ExecutionTask); } System.Threading.Tasks.Task.WaitAll(depTasks.ToArray()); if (cancellationToken.IsCancellationRequested) { return; } try { (module as IModuleExecution).Execute(context); } catch (Exception ex) { abortException = ex; cancellationSource.Cancel(); } finally { if (context.OutputStringBuilder != null && context.OutputStringBuilder.Length > 0) { Log.Info(context.OutputStringBuilder.ToString()); } if (context.ErrorStringBuilder != null && context.ErrorStringBuilder.Length > 0) { Log.Info(context.ErrorStringBuilder.ToString()); } } }); tasks.Add(task); module.ExecutionTask = task; } } try { System.Threading.Tasks.Task.WaitAll(tasks.ToArray()); } catch (System.AggregateException exception) { if (!(exception.InnerException is System.Threading.Tasks.TaskCanceledException)) { throw new Exception(exception, "Error during threaded build"); } } } } else { foreach (var rank in graph.Reverse()) { if (null != abortException) { break; } foreach (IModuleExecution module in rank) { var context = new ExecutionContext(useEvaluation, explainRebuild, immediateOutput); try { module.Execute(context); } catch (Exception ex) { abortException = ex; break; } finally { if (context.OutputStringBuilder != null && context.OutputStringBuilder.Length > 0) { Log.Info(context.OutputStringBuilder.ToString()); } if (context.ErrorStringBuilder != null && context.ErrorStringBuilder.Length > 0) { Log.Info(context.ErrorStringBuilder.ToString()); } } } } } if (null != abortException) { throw new Exception(abortException, "Error during {0}threaded build", (threadCount > 1) ? string.Empty : "non-"); } ExecutePostBuild(metaDataType); }