blob: a21ad0e190c97a2bd572015ccf916605981b40c4 [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 (
"context"
"encoding/json"
"fmt"
"os"
"strings"
)
// Arg holds the information directly parsed from the json output of `gn args <build> --list --json`.
type Arg struct {
Name string `json:"name"`
CurrentVal argValue `json:"current"`
DefaultVal argValue `json:"default"`
Comment string `json:"comment"`
Key string `json: "-"`
}
// ArgValue holds a value, its filepath and line number, and the build associated with the value.
type argValue struct {
Val string `json:"value"`
File string `json:"file"`
Line int `json:"line"`
}
// ParseGNArgs runs the necessary gn commands and decodes the json output into a channel of GNArgs.
func ParseGNArgs(ctx context.Context, inputFiles []string, keyArgs []string) (<-chan Arg, <-chan error) {
args := make(chan Arg)
errs := make(chan error, 1)
go func() {
defer func() {
close(args)
close(errs)
}()
for _, input := range inputFiles {
select {
case <-ctx.Done():
return
default:
err := parseJson(input, keyArgs, args)
if err != nil {
errs <- err
return
}
}
}
}()
return args, errs
}
func parseJson(input string, keyArgs []string, out chan<- Arg) error {
// Open the json file.
file, err := os.Open(input)
if err != nil {
return err
}
defer file.Close()
// Decode the json into GNArgs.
var gnArgs []Arg
decoder := json.NewDecoder(file)
if err := decoder.Decode(&gnArgs); err != nil {
return err
}
// Mark the args with the relevant key and send to channel.
key := getKey(gnArgs, keyArgs)
for _, arg := range gnArgs {
arg.Key = key
out <- arg
}
return nil
}
// TODO: make sure this is sorted before stringifying
// getKey searches the decoded json for the flagged keys and builds the marker string.
func getKey(args []Arg, keys []string) string {
keyVals := make([]string, len(keys))
for _, arg := range args {
for idx, key := range keys {
if arg.Name == key {
keyVals[idx] = fmt.Sprintf("%s = %v", key, arg.CurrentVal.Val)
}
}
}
return strings.Join(keyVals, ", ")
}