github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/blueprint/bootstrap/writedocs.go (about)

     1  package bootstrap
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"html/template"
     7  	"io/ioutil"
     8  	"path/filepath"
     9  
    10  	"github.com/google/blueprint"
    11  	"github.com/google/blueprint/bootstrap/bpdoc"
    12  	"github.com/google/blueprint/pathtools"
    13  )
    14  
    15  // ModuleTypeDocs returns a list of bpdoc.ModuleType objects that contain information relevant
    16  // to generating documentation for module types supported by the primary builder.
    17  func ModuleTypeDocs(ctx *blueprint.Context) ([]*bpdoc.ModuleType, error) {
    18  	// Find the module that's marked as the "primary builder", which means it's
    19  	// creating the binary that we'll use to generate the non-bootstrap
    20  	// build.ninja file.
    21  	var primaryBuilders []*goBinary
    22  	var minibp *goBinary
    23  	ctx.VisitAllModulesIf(isBootstrapBinaryModule,
    24  		func(module blueprint.Module) {
    25  			binaryModule := module.(*goBinary)
    26  			if binaryModule.properties.PrimaryBuilder {
    27  				primaryBuilders = append(primaryBuilders, binaryModule)
    28  			}
    29  			if ctx.ModuleName(binaryModule) == "minibp" {
    30  				minibp = binaryModule
    31  			}
    32  		})
    33  
    34  	if minibp == nil {
    35  		panic("missing minibp")
    36  	}
    37  
    38  	var primaryBuilder *goBinary
    39  	switch len(primaryBuilders) {
    40  	case 0:
    41  		// If there's no primary builder module then that means we'll use minibp
    42  		// as the primary builder.
    43  		primaryBuilder = minibp
    44  
    45  	case 1:
    46  		primaryBuilder = primaryBuilders[0]
    47  
    48  	default:
    49  		return nil, fmt.Errorf("multiple primary builder modules present")
    50  	}
    51  
    52  	pkgFiles := make(map[string][]string)
    53  	ctx.VisitDepsDepthFirst(primaryBuilder, func(module blueprint.Module) {
    54  		switch m := module.(type) {
    55  		case (*goPackage):
    56  			pkgFiles[m.properties.PkgPath] = pathtools.PrefixPaths(m.properties.Srcs,
    57  				filepath.Join(SrcDir, ctx.ModuleDir(m)))
    58  		default:
    59  			panic(fmt.Errorf("unknown dependency type %T", module))
    60  		}
    61  	})
    62  
    63  	return bpdoc.ModuleTypes(pkgFiles, ctx.ModuleTypePropertyStructs())
    64  }
    65  
    66  func writeDocs(ctx *blueprint.Context, filename string) error {
    67  	moduleTypeList, err := ModuleTypeDocs(ctx)
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	buf := &bytes.Buffer{}
    73  
    74  	unique := 0
    75  
    76  	tmpl, err := template.New("file").Funcs(map[string]interface{}{
    77  		"unique": func() int {
    78  			unique++
    79  			return unique
    80  		}}).Parse(fileTemplate)
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	err = tmpl.Execute(buf, moduleTypeList)
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	err = ioutil.WriteFile(filename, buf.Bytes(), 0666)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	return nil
    96  }
    97  
    98  const (
    99  	fileTemplate = `
   100  <html>
   101  <head>
   102  <title>Build Docs</title>
   103  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
   104  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
   105  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
   106  </head>
   107  <body>
   108  <h1>Build Docs</h1>
   109  <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
   110    {{range .}}
   111      {{ $collapseIndex := unique }}
   112      <div class="panel panel-default">
   113        <div class="panel-heading" role="tab" id="heading{{$collapseIndex}}">
   114          <h2 class="panel-title">
   115            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{$collapseIndex}}" aria-expanded="false" aria-controls="collapse{{$collapseIndex}}">
   116               {{.Name}}
   117            </a>
   118          </h2>
   119        </div>
   120      </div>
   121      <div id="collapse{{$collapseIndex}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{$collapseIndex}}">
   122        <div class="panel-body">
   123          <p>{{.Text}}</p>
   124          {{range .PropertyStructs}}
   125            <p>{{.Text}}</p>
   126            {{template "properties" .Properties}}
   127          {{end}}
   128        </div>
   129      </div>
   130    {{end}}
   131  </div>
   132  </body>
   133  </html>
   134  
   135  {{define "properties"}}
   136    <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
   137      {{range .}}
   138        {{$collapseIndex := unique}}
   139        {{if .Properties}}
   140          <div class="panel panel-default">
   141            <div class="panel-heading" role="tab" id="heading{{$collapseIndex}}">
   142              <h4 class="panel-title">
   143                <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{$collapseIndex}}" aria-expanded="false" aria-controls="collapse{{$collapseIndex}}">
   144                   {{.Name}}{{range .OtherNames}}, {{.}}{{end}}
   145                </a>
   146              </h4>
   147            </div>
   148          </div>
   149          <div id="collapse{{$collapseIndex}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{$collapseIndex}}">
   150            <div class="panel-body">
   151              <p>{{.Text}}</p>
   152              {{range .OtherTexts}}<p>{{.}}</p>{{end}}
   153              {{template "properties" .Properties}}
   154            </div>
   155          </div>
   156        {{else}}
   157          <div>
   158            <h4>{{.Name}}{{range .OtherNames}}, {{.}}{{end}}</h4>
   159            <p>{{.Text}}</p>
   160            {{range .OtherTexts}}<p>{{.}}</p>{{end}}
   161            <p><i>Type: {{.Type}}</i></p>
   162            {{if .Default}}<p><i>Default: {{.Default}}</i></p>{{end}}
   163          </div>
   164        {{end}}
   165      {{end}}
   166    </div>
   167  {{end}}
   168  `
   169  )