/// <summary> /// Builds the project using the specified <see cref="IDocumenter"/> /// </summary> /// <param name="documenter">The <see cref="IDocumenter"/> to use</param> /// <param name="project">The <see cref="Project"/> to build</param> public void Build( IDocumenter documenter, Project project ) { Debug.Assert( documenter != null ); Debug.Assert( project != null ); Debug.Assert( m_workerThread == null ); m_documenter = documenter; m_project = project; m_workerThread = new Thread( new ThreadStart( ThreadProc ) ); m_workerThread.Name = "Build"; m_workerThread.IsBackground = true; m_workerThread.Priority = ThreadPriority.Normal; m_workerThread.Start(); }
/// <summary> /// Returns the documenter for the given project. /// </summary> /// <exception cref="BuildException"> /// Documenter <paramref name="documenterName" /> is not found. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="project" /> is <see langword="null" />. /// </exception> private IDocumenter CheckAndGetDocumenter(NDoc.Core.Project project, string documenterName) { IDocumenter documenter = null; if (project == null) { throw new ArgumentNullException("project"); } StringCollection documenters = new StringCollection(); foreach (IDocumenter d in project.Documenters) { documenters.Add(d.Name); // ignore case when comparing documenter names if (string.Compare(d.Name, documenterName, true, CultureInfo.InvariantCulture) == 0) { documenter = (IDocumenter)d; break; } } // throw an exception if the documenter could not be found. if (documenter == null) { if (documenters.Count == 0) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA2024"), documenterName), Location); } else { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA2025"), documenterName, StringUtils.Join(", ", documenters)), Location); } } return(documenter); }
public static int Main(string[] args) { try { WriteLogoBanner(); project = new Project(); documenter = project.GetDocumenter("MSDN"); if (documenter == null) { //MSDN documenter not found, pick the first one available. if (project.Documenters.Count > 0) { documenter = (IDocumenter)project.Documenters[0]; } else { throw new ApplicationException("Could not find any documenter assemblies."); } } int maxDepth = 20; //to limit recursion depth bool propertiesSet = false; bool projectSet = false; if (args.Length==0) { WriteUsage(); return 1; } if (args[0].ToLower().StartsWith("-help")) { WriteHelp(args); return 1; } foreach (string arg in args) { if (arg.StartsWith("-")) { if (string.Compare(arg, "-verbose", true) == 0) { Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); } else { string[] pair = arg.Split('='); if (pair.Length == 2) { string name = pair[0].Substring(1); string val = pair[1]; switch (name.ToLower()) { case "documenter": if (propertiesSet) { throw new ApplicationException("The documenter name must be specified before any documenter specific options."); } if (projectSet) { throw new ApplicationException("The documenter name must be specified before the project file."); } documenter = project.GetDocumenter(val.Replace("_"," ")); if (documenter == null) { throw new ApplicationException("The specified documenter name is invalid."); } break; case "project": if (propertiesSet) { throw new ApplicationException("The project file must be specified before any documenter specific options."); } project = new Project(); documenter = project.GetDocumenter(documenter.Name); documenter.Config.SetProject(project); project.Read(val); projectSet = true; break; case "recurse": string[] recPair = val.Split(','); if (2 == recPair.Length) { maxDepth = Convert.ToInt32(recPair[1]); } RecurseDir(recPair[0], maxDepth); break; case "namespacesummaries": using(StreamReader streamReader = new StreamReader(val)) { XmlTextReader reader = new XmlTextReader(streamReader); reader.MoveToContent(); project.Namespaces.Read(reader); reader.Close(); streamReader.Close(); } break; case "referencepath": project.ReferencePaths.Add(new ReferencePath(val)); break; default: documenter.Config.SetValue(name, val); propertiesSet = true; break; } } } } else if (arg.IndexOf(',') != -1) { string[] pair = arg.Split(','); if (pair.Length == 2) { project.AssemblySlashDocs.Add( new AssemblySlashDoc(pair[0], pair[1])); } } else { string doc = Path.ChangeExtension(arg, ".xml"); if (File.Exists(doc)) { project.AssemblySlashDocs.Add( new AssemblySlashDoc(arg, doc)); } else { project.AssemblySlashDocs.Add( new AssemblySlashDoc(arg, "")); } } } if (project.AssemblySlashDocs.Count == 0) { WriteUsage(); return 1; } else { documenter.DocBuildingStep += new DocBuildingEventHandler(DocBuildingStepHandler); documenter.Build(project); return 0; } } catch( Exception except ) { string errorText= BuildExceptionText(except); Console.WriteLine(errorText); System.Diagnostics.Trace.WriteLine(errorText); return 2; } }
private static void WriteHelpDocParameter(IDocumenter documenter,string propertyName) { PropertyInfo foundProperty=null; foreach (PropertyInfo property in documenter.Config.GetProperties()) { if (string.Compare(property.Name, propertyName, true) == 0) { foundProperty=property; break; } } if (foundProperty==null) { Console.WriteLine("{0} is not a property of the {1} documenter...", propertyName, documenter.Name); Console.WriteLine(""); WriteHelpAvailableDocParameters(documenter); } else { WriteHelpPropertyDetails(foundProperty); } }
private static void WriteHelpAvailableDocParameters(IDocumenter documenter) { Console.WriteLine("available properties with the {0} documenter:", documenter.Name); foreach (PropertyInfo property in documenter.Config.GetProperties()) { if (!property.IsDefined(typeof(NonPersistedAttribute),true)) { Console.WriteLine(" " + property.Name); } } }
/// <summary> /// /// </summary> /// <param name="documenter"></param> /// <param name="project"></param> public BuildWorker(IDocumenter documenter, Project project) { m_documenter = documenter; m_project = project; }
/// <summary> /// Generates an NDoc project and builds the documentation. /// </summary> protected override void ExecuteTask() { // ensure base directory is set, even if fileset was not initialized // from XML if (Assemblies.BaseDirectory == null) { Assemblies.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } if (Summaries.BaseDirectory == null) { Summaries.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } if (ReferencePaths.BaseDirectory == null) { ReferencePaths.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } // Make sure there is at least one included assembly. This can't // be done in the Initialize() method because the files might // not have been built at startup time. if (Assemblies.FileNames.Count == 0) { throw new BuildException(ResourceUtils.GetString("NA2020"), Location); } // create NDoc Project NDoc.Core.Project project = null; try { project = new NDoc.Core.Project(); } catch (Exception ex) { throw new BuildException(ResourceUtils.GetString("NA2021"), Location, ex); } // set-up probe path, meaning list of directories where NDoc searches // for documenters // by default, NDoc scans the startup path of the app, so we do not // need to add this explicitly string privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath; if (privateBinPath != null) { // have NDoc also probe for documenters in the privatebinpath foreach (string relativePath in privateBinPath.Split(Path.PathSeparator)) { project.AppendProbePath(Path.Combine( AppDomain.CurrentDomain.BaseDirectory, relativePath)); } } // check for valid documenters (any other validation can be done by NDoc itself at project load time) foreach (XmlNode node in _docNodes) { //skip non-nant namespace elements and special elements like comments, pis, text, etc. if (!(node.NodeType == XmlNodeType.Element) || !node.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant"))) { continue; } string documenterName = node.Attributes["name"].Value; CheckAndGetDocumenter(project, documenterName); } // write documenter project settings to temp file string projectFileName = Path.GetTempFileName(); Log(Level.Verbose, ResourceUtils.GetString("String_WritingProjectSettings"), projectFileName); XmlTextWriter writer = new XmlTextWriter(projectFileName, Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("project"); // write assemblies section writer.WriteStartElement("assemblies"); foreach (string assemblyPath in Assemblies.FileNames) { string docPath = Path.ChangeExtension(assemblyPath, ".xml"); writer.WriteStartElement("assembly"); writer.WriteAttributeString("location", assemblyPath); if (File.Exists(docPath)) { writer.WriteAttributeString("documentation", docPath); } writer.WriteEndElement(); } writer.WriteEndElement(); // write summaries section StringBuilder sb = new StringBuilder(); foreach (string summaryPath in Summaries.FileNames) { // write out the namespace summary nodes try { XmlTextReader tr = new XmlTextReader(summaryPath); tr.MoveToContent(); // skip XmlDeclaration and Processing Instructions sb.Append(tr.ReadOuterXml()); tr.Close(); } catch (IOException ex) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA2022"), summaryPath), Location, ex); } } writer.WriteRaw(sb.ToString()); // write out the documenters section writer.WriteStartElement("documenters"); foreach (XmlNode node in _docNodes) { //skip non-nant namespace elements and special elements like comments, pis, text, etc. if (!(node.NodeType == XmlNodeType.Element) || !node.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant"))) { continue; } writer.WriteRaw(node.OuterXml); } writer.WriteEndElement(); // end project element writer.WriteEndElement(); writer.Close(); try { // read NDoc project file Log(Level.Verbose, ResourceUtils.GetString("String_NDocProjectFile"), Path.GetFullPath(projectFileName)); project.Read(projectFileName); // add additional directories to search for referenced assemblies if (ReferencePaths.DirectoryNames.Count > 0) { foreach (string directory in ReferencePaths.DirectoryNames) { project.ReferencePaths.Add(new ReferencePath(directory)); } } foreach (XmlNode node in _docNodes) { //skip non-nant namespace elements and special elements like comments, pis, text, etc. if (!(node.NodeType == XmlNodeType.Element) || !node.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant"))) { continue; } string documenterName = node.Attributes["name"].Value; IDocumenter documenter = CheckAndGetDocumenter(project, documenterName); // hook up events for feedback during the build documenter.DocBuildingStep += new DocBuildingEventHandler(OnDocBuildingStep); documenter.DocBuildingProgress += new DocBuildingEventHandler(OnDocBuildingProgress); // build documentation documenter.Build(project); } } catch (Exception ex) { throw new BuildException(ResourceUtils.GetString("NA2023"), Location, ex); } }
private void ThreadProc() { GC.Collect(); Debug.WriteLine("Memory before build: " + GC.GetTotalMemory(false).ToString()); try { m_documenter.DocBuildingStep += new DocBuildingEventHandler(m_documenter_DocBuildingStep); // Build the documentation. m_documenter.Build(m_project); } catch ( Exception ex ) { if ( App.GetInnermostException( ex ) is ThreadAbortException ) m_buildStatus.BuildCancelled(); else m_buildStatus.BuildException( ex ); } finally { m_documenter.DocBuildingStep -= new DocBuildingEventHandler(m_documenter_DocBuildingStep); m_buildStatus.BuildComplete(); m_project = null; m_documenter = null; lock( this ) m_workerThread = null; GC.Collect(); Debug.WriteLine("Memory after build: " + GC.GetTotalMemory(false).ToString()); } }