blob: da3bd2078401bf0a618356e0bd9ad91a8668cc92 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package gndoc
import (
"fmt"
"io"
"sort"
"strings"
)
type ArgMap struct {
argLookup map[string][]string // map of arg names to keys for lookup
args map[string][]Arg // map of key names to relevant args
sources *SourceMap // map of existing source locations for linkifying
}
// NewArgMap returns a pointer to an
func NewArgMap(sources *SourceMap) *ArgMap {
return &ArgMap{
argLookup: make(map[string][]string),
args: make(map[string][]Arg),
sources: sources,
}
}
// AddArg creates args from GNArgs and adds them to the maps
func (a *ArgMap) AddArgs(gnArgs <-chan Arg) {
for gnArg := range gnArgs {
a.AddArg(gnArg)
}
}
func (a *ArgMap) AddArg(gnArg Arg) {
a.args[gnArg.Key] = append(a.args[gnArg.Key], gnArg)
a.argLookup[gnArg.Name] = append(a.argLookup[gnArg.Name], gnArg.Key)
}
// sortedArgs returns the list of args in the appropriate order to print.
func (a *ArgMap) sortedArgs() (map[string]map[string][]Arg, []string) {
numKeys := len(a.args)
args := make(map[string]map[string][]Arg)
// For each arg, we need to push it into the appropiate list.
for _, gnArgs := range a.args {
for _, gnArg := range gnArgs {
// Lookup the keys associated with this arg & sort & stringify.
keys, _ := a.argLookup[gnArg.Name]
if len(keys) == numKeys {
// Incoming keys will always have an `=`, and so this is an okay value.
keys = []string{"all"}
}
key := strings.Join(keys, ", ")
_, ok := args[key]
if !ok {
args[key] = make(map[string][]Arg)
}
args[key][gnArg.Name] = append(args[key][gnArg.Name], gnArg)
}
}
// Get the keys in alphabetical order
keys := make([]string, 0, numKeys)
for k := range args {
// Sort by name first, then by key
for argName := range args[k] {
sort.Slice(args[k][argName], func(i, j int) bool { return args[k][argName][i].Key < args[k][argName][j].Key })
}
keys = append(keys, k)
}
sort.Strings(keys)
return args, keys
}
// EmitMarkdown emits Markdown text for the map of arguments.
func (a *ArgMap) EmitMarkdown(out io.Writer) {
// Emit a header.
fmt.Fprintf(out, "# %s\n\n", pageTitle)
gnArgsMap, keys := a.sortedArgs()
for _, name := range keys {
if name == "all" {
fmt.Fprintf(out, "## All builds\n\n")
} else {
fmt.Fprintf(out, "## `%s`\n\n", name)
}
for _, gnArgs := range gnArgsMap[name] {
writeArgs(gnArgs, out, a.sources)
}
}
}