Integrating Sandcastle doc generation to your NAnt builds

NAnt is an open source software tool for automating software build processes. It is based on Apache Ant and targeted at the .NET environment whereas Ant is a more generic cross-platform tool principally used by Java programmers.

 

Brett Burch from https://www.brettresources.net/ recently emailed me the following information about integrating Sandcastle document generation process into NAnt build process. Assuming you have a tree structure as follows, adding automated generation through the September CTP of Sandcastle into your NAnt build process is very painless. Even if you don’t have an identical structure, you can change a few lines of text and be on your way. Here is that structure shown graphically via WinCVS.

Directory structure

 

 

I have included the Sandcastle icons, scripts, and styles that come with the download in my CVS tree. Also stored in CVS are a .bat file which NAnt fires up and a sandcastle.config file slightly different than the example provided with the download. NAnt pulls the documentation generation items out of CVS and then runs a batch file to create the documentation from those items. The NAnt target of interest is simply

<target name="docs" depends="build">

    <call target="cvs_doc" cascade="false" />

    <exec program="${path::combine(build.dir, project::get-name() + '')}/doc/GenerateDocumentation_tokenreplaced.bat"/>

</target>

There are a few targets that this target requires in addition to the obvious build target. They are included below for reference.

<target name="cvs_doc" description="checks out doc items">

    <property name="cvs.module.current" value="${cvs.module.doc}" />

    <call target="cvs_checkout" cascade="false" />

    <call target="cvs_doc_replacetoken" />

</target>

<target name="cvs_doc_replacetoken" description="sets token to text in doc bat file">

    <copy

            file="${path::combine(build.dir, project::get-name() + '')}/doc/GenerateDocumentation.bat"

            tofile="${path::combine(build.dir, project::get-name() + '')}/doc/GenerateDocumentation_tokenreplaced.bat"

            overwrite="true">

      <filterchain>

        <replacetokens>

          <token key="BUILDDIR" value="${build.dir}" />

        </replacetokens>

      </filterchain>

    </copy>

</target>

 

<target name="cvs_checkout" depends="init,cvs_passfile" description="checks out cvs.module.current module">

    <cvs-checkout

      destination="${build.dir}"

      cvsroot="${cvs.root}"

      module="${cvs.module.current}"

      passfile="${cvs.passfile.location}"

    cvsfullpath="${cvs.exe.location}"

            />

  </target>

The critical piece which generates the documentation for you (following the build of your source) is the GenerateDocumentation_tokenreplaced.bat file. That file assumes you tell it the root of your folder / tree structure via NAnt’s replacetokens feature, you have installed Sandcastle in the default location, and your sandcastle.config file is slightly modified from the supplied CTP example.

Here is that .bat file in its entirety:

@echo off

echo start documentation generation

cd @BUILDDIR@\SalesForce\doc

if not exist comments mkdir comments

:: comment XML files need copied to the comments folder

copy ..\..\bin\SalesForce*.xml comments

MRefBuilder "..\..\bin\SalesForce*.*" /out:reflection.org /dep:"c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Configuration.dll"

XslTransform /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\AddOverloads.xsl" reflection.org /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\AddGuidFilenames.xsl" /out:reflection.xml

XslTransform /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToManifest.xsl" reflection.xml /out:manifest.xml

if not exist Output mkdir Output

::kill the current Output\html folder if it exists

if exist Output\html RMDIR Output\html /s /Q

if not exist Output\html mkdir Output\html

::the next 6 lines are only required if you do not store Sandcastle items in source control

if not exist Output\icons mkdir Output\icons

if not exist Output\scripts mkdir Output\scripts

if not exist Output\styles mkdir Output\styles

copy "C:\Program Files\Sandcastle\Presentation\Prototype\icons\*" Output\icons

copy "C:\Program Files\Sandcastle\Presentation\Prototype\scripts\*" Output\scripts

copy "C:\Program Files\Sandcastle\Presentation\Prototype\styles\*" Output\styles

BuildAssembler /config:sandcastle.config manifest.xml

::Generate HTML help project -- do not rename from test

XslTransform /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToChmProject.xsl" reflection.xml /out:Output\Test.hhp

::Generate table of contents for HTML help project -- do not rename from test

XslTransform /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToChmContents.xsl" reflection.xml /arg:html=Output\html /out:Output\Test.hhc

::Generate Index information -- do not rename from test

XslTransform /xsl:"C:\Program Files\Sandcastle\ProductionTransforms\ReflectionToChmIndex.xsl" reflection.xml /out:Output\Test.hhk

"%ProgramFiles%\HTML Help Workshop\hhc.exe" Output\Test.hhp

::put the final deliverable in the correct location

copy Output\Test.chm ..\..\doc\SalesForce.chm

echo end documentation generation

The change to the sandcastle.config file mentioned comes in line 53 of the sample file, where <data files="comments.xml" /> becomes <data files="comments\*.xml" />. This is to ensure documentation from all assemblies is compiled into your CHM file. I have also changed the relative path references so the .bat file can be run from anywhere as long as Sandcastle is installed. The entire modified file is available at https://www.brettresources.net/dotnet/samples/sandcastle.config.xml (note the file extension change). Your final result should be as shown below.

 

Result

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

This is purely an example and we are not affiliated with SalesForce.com in any way.

 

 

Sandcastle_NAnt_Cvs.PNG