Exemplo n.º 1
0
        /// <summary>
        /// Generate HTML documentation for all the tasks
        /// </summary>
        /// <param name="NameToTask">Map of task name to implementation</param>
        /// <param name="OutputFile">Output file</param>
        static void GenerateDocumentation(Dictionary <string, ScriptTask> NameToTask, FileReference OutputFile)
        {
            // Find all the assemblies containing tasks
            Assembly[] TaskAssemblies = NameToTask.Values.Select(x => x.ParametersClass.Assembly).Distinct().ToArray();

            // Read documentation for each of them
            Dictionary <string, XmlElement> MemberNameToElement = new Dictionary <string, XmlElement>();

            foreach (Assembly TaskAssembly in TaskAssemblies)
            {
                string XmlFileName = Path.ChangeExtension(TaskAssembly.Location, ".xml");
                if (File.Exists(XmlFileName))
                {
                    // Read the document
                    XmlDocument Document = new XmlDocument();
                    Document.Load(XmlFileName);

                    // Parse all the members, and add them to the map
                    foreach (XmlElement Element in Document.SelectNodes("/doc/members/member"))
                    {
                        string Name = Element.GetAttribute("name");
                        MemberNameToElement.Add(Name, Element);
                    }
                }
            }

            // Create the output directory
            if (FileReference.Exists(OutputFile))
            {
                FileReference.MakeWriteable(OutputFile);
            }
            else
            {
                DirectoryReference.CreateDirectory(OutputFile.Directory);
            }

            // Write the output file
            LogInformation("Writing {0}...", OutputFile);
            using (StreamWriter Writer = new StreamWriter(OutputFile.FullName))
            {
                Writer.WriteLine("<html>");
                Writer.WriteLine("  <head>");
                Writer.WriteLine("    <style>");
                Writer.WriteLine("      table { border-collapse: collapse }");
                Writer.WriteLine("      table, th, td { border: 1px solid black; }");
                Writer.WriteLine("    </style>");
                Writer.WriteLine("  </head>");
                Writer.WriteLine("  <body>");
                Writer.WriteLine("    <h1>BuildGraph Tasks</h1>");
                foreach (string TaskName in NameToTask.Keys.OrderBy(x => x))
                {
                    // Get the task object
                    ScriptTask Task = NameToTask[TaskName];

                    // Get the documentation for this task
                    XmlElement TaskElement;
                    if (MemberNameToElement.TryGetValue("T:" + Task.TaskClass.FullName, out TaskElement))
                    {
                        // Write the task heading
                        Writer.WriteLine("    <h2>{0}</h2>", TaskName);
                        Writer.WriteLine("    <p>{0}</p>", TaskElement.SelectSingleNode("summary").InnerXml.Trim());

                        // Start the parameter table
                        Writer.WriteLine("    <table>");
                        Writer.WriteLine("      <tr>");
                        Writer.WriteLine("        <th>Attribute</th>");
                        Writer.WriteLine("        <th>Type</th>");
                        Writer.WriteLine("        <th>Usage</th>");
                        Writer.WriteLine("        <th>Description</th>");
                        Writer.WriteLine("      </tr>");

                        // Document the parameters
                        foreach (string ParameterName in Task.NameToParameter.Keys)
                        {
                            // Get the parameter data
                            ScriptTaskParameter Parameter = Task.NameToParameter[ParameterName];

                            // Get the documentation for this parameter
                            XmlElement ParameterElement;
                            if (MemberNameToElement.TryGetValue("F:" + Parameter.FieldInfo.DeclaringType.FullName + "." + Parameter.Name, out ParameterElement))
                            {
                                string TypeName = Parameter.FieldInfo.FieldType.Name;
                                if (Parameter.ValidationType != TaskParameterValidationType.Default)
                                {
                                    StringBuilder NewTypeName = new StringBuilder(Parameter.ValidationType.ToString());
                                    for (int Idx = 1; Idx < NewTypeName.Length; Idx++)
                                    {
                                        if (Char.IsLower(NewTypeName[Idx - 1]) && Char.IsUpper(NewTypeName[Idx]))
                                        {
                                            NewTypeName.Insert(Idx, ' ');
                                        }
                                    }
                                    TypeName = NewTypeName.ToString();
                                }

                                Writer.WriteLine("      <tr>");
                                Writer.WriteLine("         <td>{0}</td>", ParameterName);
                                Writer.WriteLine("         <td>{0}</td>", TypeName);
                                Writer.WriteLine("         <td>{0}</td>", Parameter.bOptional? "Optional" : "Required");
                                Writer.WriteLine("         <td>{0}</td>", ParameterElement.SelectSingleNode("summary").InnerXml.Trim());
                                Writer.WriteLine("      </tr>");
                            }
                        }

                        // Always include the "If" attribute
                        Writer.WriteLine("     <tr>");
                        Writer.WriteLine("       <td>If</td>");
                        Writer.WriteLine("       <td>Condition</td>");
                        Writer.WriteLine("       <td>Optional</td>");
                        Writer.WriteLine("       <td>Whether to execute this task. It is ignored if this condition evaluates to false.</td>");
                        Writer.WriteLine("     </tr>");

                        // Close the table
                        Writer.WriteLine("    <table>");
                    }
                }
                Writer.WriteLine("  </body>");
                Writer.WriteLine("</html>");
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generate HTML documentation for all the tasks
        /// </summary>
        /// <param name="NameToTask">Map of task name to implementation</param>
        /// <param name="OutputFile">Output file</param>
        static void GenerateDocumentation(Dictionary <string, ScriptTask> NameToTask, FileReference OutputFile)
        {
            // Find all the assemblies containing tasks
            Assembly[] TaskAssemblies = NameToTask.Values.Select(x => x.ParametersClass.Assembly).Distinct().ToArray();

            // Read documentation for each of them
            Dictionary <string, XmlElement> MemberNameToElement = new Dictionary <string, XmlElement>();

            foreach (Assembly TaskAssembly in TaskAssemblies)
            {
                string XmlFileName = Path.ChangeExtension(TaskAssembly.Location, ".xml");
                if (File.Exists(XmlFileName))
                {
                    // Read the document
                    XmlDocument Document = new XmlDocument();
                    Document.Load(XmlFileName);

                    // Parse all the members, and add them to the map
                    foreach (XmlElement Element in Document.SelectNodes("/doc/members/member"))
                    {
                        string Name = Element.GetAttribute("name");
                        MemberNameToElement.Add(Name, Element);
                    }
                }
            }

            // Create the output directory
            DirectoryReference.CreateDirectory(OutputFile.Directory);
            FileReference.MakeWriteable(OutputFile);
            Log("Writing {0}...", OutputFile);

            // Parse the engine version
            BuildVersion Version;

            if (!BuildVersion.TryRead(BuildVersion.GetDefaultFileName(), out Version))
            {
                throw new AutomationException("Couldn't read Build.version");
            }

            // Write the output file
            using (StreamWriter Writer = new StreamWriter(OutputFile.FullName))
            {
                Writer.WriteLine("Availability: NoPublish");
                Writer.WriteLine("Title: BuildGraph Predefined Tasks");
                Writer.WriteLine("Crumbs: %ROOT%, Programming, Programming/Development, Programming/Development/BuildGraph, Programming/Development/BuildGraph/BuildGraphScriptTasks");
                Writer.WriteLine("Description: This is a procedurally generated markdown page.");
                Writer.WriteLine("version: {0}.{1}", Version.MajorVersion, Version.MinorVersion);
                Writer.WriteLine("parent:Programming/Development/BuildGraph/BuildGraphScriptTasks");
                Writer.WriteLine();
                foreach (string TaskName in NameToTask.Keys.OrderBy(x => x))
                {
                    // Get the task object
                    ScriptTask Task = NameToTask[TaskName];

                    // Get the documentation for this task
                    XmlElement TaskElement;
                    if (MemberNameToElement.TryGetValue("T:" + Task.TaskClass.FullName, out TaskElement))
                    {
                        // Write the task heading
                        Writer.WriteLine("### {0}", TaskName);
                        Writer.WriteLine();
                        Writer.WriteLine(ConvertToMarkdown(TaskElement.SelectSingleNode("summary")));
                        Writer.WriteLine();

                        // Document the parameters
                        List <string[]> Rows = new List <string[]>();
                        foreach (string ParameterName in Task.NameToParameter.Keys)
                        {
                            // Get the parameter data
                            ScriptTaskParameter Parameter = Task.NameToParameter[ParameterName];

                            // Get the documentation for this parameter
                            XmlElement ParameterElement;
                            if (MemberNameToElement.TryGetValue("F:" + Parameter.FieldInfo.DeclaringType.FullName + "." + Parameter.Name, out ParameterElement))
                            {
                                string TypeName = Parameter.FieldInfo.FieldType.Name;
                                if (Parameter.ValidationType != TaskParameterValidationType.Default)
                                {
                                    StringBuilder NewTypeName = new StringBuilder(Parameter.ValidationType.ToString());
                                    for (int Idx = 1; Idx < NewTypeName.Length; Idx++)
                                    {
                                        if (Char.IsLower(NewTypeName[Idx - 1]) && Char.IsUpper(NewTypeName[Idx]))
                                        {
                                            NewTypeName.Insert(Idx, ' ');
                                        }
                                    }
                                    TypeName = NewTypeName.ToString();
                                }

                                string[] Columns = new string[4];
                                Columns[0] = ParameterName;
                                Columns[1] = TypeName;
                                Columns[2] = Parameter.bOptional? "Optional" : "Required";
                                Columns[3] = ConvertToMarkdown(ParameterElement.SelectSingleNode("summary"));
                                Rows.Add(Columns);
                            }
                        }

                        // Always include the "If" attribute
                        string[] IfColumns = new string[4];
                        IfColumns[0] = "If";
                        IfColumns[1] = "Condition";
                        IfColumns[2] = "Optional";
                        IfColumns[3] = "Whether to execute this task. It is ignored if this condition evaluates to false.";
                        Rows.Add(IfColumns);

                        // Get the width of each column
                        int[] Widths = new int[4];
                        for (int Idx = 0; Idx < 4; Idx++)
                        {
                            Widths[Idx] = Rows.Max(x => x[Idx].Length);
                        }

                        // Format the markdown table
                        string Format = String.Format("| {{0,-{0}}} | {{1,-{1}}} | {{2,-{2}}} | {{3,-{3}}} |", Widths[0], Widths[1], Widths[2], Widths[3]);
                        Writer.WriteLine(Format, "", "", "", "");
                        Writer.WriteLine(Format, new string('-', Widths[0]), new string('-', Widths[1]), new string('-', Widths[2]), new string('-', Widths[3]));
                        for (int Idx = 0; Idx < Rows.Count; Idx++)
                        {
                            Writer.WriteLine(Format, Rows[Idx][0], Rows[Idx][1], Rows[Idx][2], Rows[Idx][3]);
                        }

                        // Blank line before next task
                        Writer.WriteLine();
                    }
                }
            }
        }