예제 #1
0
        public void Execute(Project p)
        {
            // generate temporary filename
            string tempFileName;

            try
            {
                var protoFilename = Path.GetTempFileName();

                // build more unique filename (include timestamp)
                tempFileName = string.Format("{0}{1}{2}", DateTime.Now.ToFileTime(), Path.GetFileName(protoFilename), ".cmd");

                // prep filename with actual path
                tempFileName = Path.Combine(Path.GetDirectoryName(protoFilename), tempFileName);

                // move file to new .cmd
                File.Move(protoFilename, tempFileName);
            }
            catch (Exception e)
            {
                log.Error("Failed to generate temporary command script", e);
                throw BuilderException.CreateFailedToStartException(p, e);
            }

            TextWriter writer = null;

            if (p == null)
            {
                throw new BuilderException("No project provided", null);
            }

            try
            {
                if (ManagedBuilderSettings.IsDebug && ManagedBuilderSettings.DebugGenerateSingleFile)
                {
                    writer = DebugCommandFile;
                    Monitor.Enter(DebugCommandFile);
                }
                else
                {
                    var fs = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
                    writer = new StreamWriter(fs);
                }

                if (!ManagedBuilderSettings.CommandLineConfig.FrameworkCommands.ContainsKey(p.Framework))
                {
                    throw new BuilderException("Unsupported framework", p);
                }

                log.DebugFormat("{0}:Building command line script in [{1}]", p.Name, tempFileName);

                // setup property manager for this compilation instance
                var propMan = new PropertyManager();

                var projectPath = p.Path;
                if (!Path.IsPathRooted(projectPath))
                {
                    projectPath = Path.Combine(PropertyManager.Common["build.directory"], projectPath);
                }

                log.DebugFormat("Project file: {0}", projectPath);
                log.DebugFormat("Project platform: {0}", p.PlatformName);
                log.DebugFormat("Project config: {0}", p.ConfigurationName);
                log.DebugFormat("Project build options: {0}", p.BuildOpt);
                log.DebugFormat("Project location: {0}", Path.GetDirectoryName(projectPath));

                propMan.Add("project.file", projectPath);
                propMan.Add("project.buildopts", p.BuildOpt);
                propMan.Add("project.sccpath", p.SccPath);
                propMan.Add("project.platform", p.PlatformName);
                propMan.Add("project.configuration", p.ConfigurationName);
                propMan.AddDirectoryProperty("project.dir", Path.GetDirectoryName(projectPath));

                var cmdlet = ManagedBuilderSettings.CommandLineConfig.FrameworkCommands[p.Framework];

                var cmdletOut = string.Format("call {0} {1}",
                                              propMan.Evaluate(cmdlet.Commandlet), propMan.Evaluate(cmdlet.Arguments));
                writer.WriteLine(cmdletOut);
                log.DebugFormat("{0}: {1}", p.Name, cmdletOut);

                // setup binplace
                if (ManagedBuilderSettings.CommandLineConfig.BinPlaceEnabled)
                {
                    // location where binplace is stored
                    var binPlaceLocation = propMan.Evaluate(
                        ManagedBuilderSettings.CommandLineConfig.BinPlaceLocation);
                    var binPlaceFile = propMan.Evaluate(
                        ManagedBuilderSettings.CommandLineConfig.BinPlaceFilename);
                    var binPlaceRoot = propMan.Evaluate(
                        ManagedBuilderSettings.CommandLineConfig.BinPlaceRoot);

                    foreach (var output in p.Outputs)
                    {
                        var actualDestPath = "";
                        if (!String.IsNullOrEmpty(output.DestPath))
                        {
                            actualDestPath = string.Format(
                                "-b {0} ",
                                output.DestPath);
                        }

                        foreach (var path in output.PathList)
                        {
                            if (string.IsNullOrEmpty(path))
                            {
                                log.Warn("Found an empty path in project outputs");
                                continue;
                            }

                            var binPlaceOut = string.Format(
                                "{4} {0} -r {1} -p {2} {3}",
                                actualDestPath,
                                binPlaceRoot,
                                // todo app.config needs to be set so that these values are evaluated
                                Path.Combine(PropertyManager.Common["build.directory"], binPlaceFile),
                                Path.Combine(PropertyManager.Common["build.directory"], path),
                                binPlaceLocation
                                );

                            // write output to batch script
                            writer.WriteLine(binPlaceOut);
                            log.DebugFormat("{0}: {1}", p.Name, binPlaceOut);
                        }
                    }
                }

                if (ManagedBuilderSettings.IsDebug && ManagedBuilderSettings.DebugGenerateSingleFile)
                {
                    Monitor.Exit(DebugCommandFile);
                    DebugCommandFile.Flush();
                }
                else
                {
                    writer.Close();
                }

                log.DebugFormat("{0}: Executing command line script [{1}]", p.Name, tempFileName);
                var startInfo = new ProcessStartInfo();
                startInfo.Arguments =
                    string.Format("/c \"{0}\"", tempFileName);
                startInfo.FileName = "cmd.exe";
                //startInfo.RedirectStandardOutput = true;
                startInfo.WindowStyle     = ProcessWindowStyle.Hidden;
                startInfo.CreateNoWindow  = true;
                startInfo.UseShellExecute = false;

                // todo: make it changeable via config
                startInfo.WorkingDirectory = PropertyManager.Common["build.directory"];

                try
                {
                    var process = Process.Start(startInfo);
                    if (process == null)
                    {
                        throw BuilderException.CreateFailedToStartException(p);
                    }

                    using (process)
                    {
                        process.WaitForExit();

                        if (process.ExitCode != 0)
                        {
                            throw BuilderException.CreateBuildFailedDueToExitCodeException(p, process.ExitCode);
                        }
                    }
                }
                catch (BuilderException be)
                {
                    throw;
                }
                catch (Exception e)
                {
                    throw BuilderException.CreateFailedToStartException(p, e);
                }
            }
            finally
            {
                if (!ManagedBuilderSettings.IsDebug)
                {
                    File.Delete(tempFileName);
                }
            }
        }
예제 #2
0
        public static void LoadFromFile(string filename)
        {
            #region Config file loading and verification
            var doc = new XmlDocument();
            try
            {
                doc.Load(File.OpenRead(filename));
            }
            catch (Exception e)
            {
                throw ConfigurationException.AppConfigLoadFailure(e);
            }

            var xnList = doc.GetElementsByTagName("mbuilder");

            if (xnList.Count != 1)
            {
                throw ConfigurationException.MultipleMBuilderSettings();
            }
            #endregion

            var mbuildRoot = xnList[0] as XmlElement;
            if (mbuildRoot == null)
            {
                throw ConfigurationException.ConfigurationReadFailure();
            }

            var nodeList = mbuildRoot.SelectSingleNode("setup/debug") as XmlElement;
            if (nodeList != null && nodeList.HasAttribute("enabled"))
            {
                IsDebug = nodeList.Attributes["enabled"].Value.ToLower() == bool.TrueString.ToLower();
            }
            else
            {
                IsDebug = false;
            }

            var pm = new PropertyManager();

            nodeList = mbuildRoot.SelectSingleNode("setup/asyncbuilders") as XmlElement;
            if (nodeList != null && nodeList.HasAttribute("count"))
            {
                var rawBuilderCount = nodeList.Attributes["count"].Value;
                var strBuildCount   = pm.Evaluate(rawBuilderCount);
                var bldCount        = 0;
                if (!Int32.TryParse(strBuildCount, out bldCount))
                {
                    throw ConfigurationException.ConfigurationReadFailure("setup/asyncbuilders");
                }

                MaximumBuilders = bldCount;
            }
            else
            {
                MaximumBuilders = Environment.ProcessorCount;
            }

            Log.DebugFormat("Debug Mode: {0}", IsDebug);
            Log.DebugFormat("Asynchronous Builders: {0}", MaximumBuilders);

            nodeList = mbuildRoot.SelectSingleNode("builders/commandlinebuilder") as XmlElement;
            if (nodeList != null)
            {
                CommandLineConfig.Configure(nodeList);
            }
        }