blob: 9fbb32a833145264f74c0096956a6ca285649609 [file] [log] [blame]
// Copyright 2017 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.
// This file contains a program that reads cobalt configuration in a YAML format
// and outputs it as a CobaltRegistry serialized protocol buffer.
package main
import (
"config"
"config_parser"
"config_validator"
"flag"
"fmt"
"os"
"source_generator"
"github.com/golang/glog"
"google.golang.org/protobuf/proto"
)
var (
skipValidation = flag.Bool("skip_validation", false, "Skip validating the config, write it no matter what.")
depFile = flag.String("dep_file", "", "Generate a depfile (see gn documentation) that lists all the project configuration files. Requires -output_file and -config_dir.")
excludeProjects flagList
includeProjects flagList
includeCustomers flagList
)
type flagList []string
func (f *flagList) String() string {
return fmt.Sprintf("%q", *f)
}
func (f *flagList) Set(value string) error {
*f = append(*f, value)
return nil
}
// Initialization function that is run before any main().
func init() {
flag.Var(&excludeProjects, "exclude_project", "Projects to exclude from the config directories, can be specified multiple times. Projects are identified by a colon separated 'customer_id:project_id'.")
flag.Var(&includeProjects, "include_project", "Projects to include from the config directories, can be specified multiple times. Projects are identified by a colon separated 'customer_id:project_id'.")
flag.Var(&includeCustomers, "include_customer", "Customers to include from the config directories, can be specified multiple times. Customers are identified by their customer_id.")
}
func fail(step string, err error) {
glog.Errorf("\n\nFailed to %s:\n%v\n\n", step, err)
os.Exit(1)
}
func main() {
flag.Parse()
// If the location of a depfile is specified, output the depfile.
if *depFile != "" {
configFiles, err := config_parser.GetConfigFilesListFromFlags()
if err != nil {
fail("get config files", err)
}
if err := source_generator.WriteDepFileFromFlags(configFiles, *depFile); err != nil {
fail("write dep file", err)
}
}
// First, we parse the configuration from the specified location.
config_datas, err := config_parser.ParseProjectConfigDataFromFlags()
if err != nil {
fail("parse registry", err)
}
// Filter out the projects that should not be included.
if len(excludeProjects) > 0 {
if config_datas, err = config_parser.RemoveExcludedProjects(excludeProjects, config_datas); err != nil {
fail("remove excluded projects", err)
}
}
// Filter to only the customers/projects that should be included.
if len(includeProjects) > 0 || len(includeCustomers) > 0 {
if config_datas, err = config_parser.RemoveProjectsNotIncluded(includeCustomers, includeProjects, config_datas); err != nil {
fail("remove customers/projects not included", err)
}
}
config_parser.ExpandDefaults(config_datas)
// Unless otherwise specified, validate the registry.
if !*skipValidation {
if err = config_validator.ValidateProjectConfigDatas(config_datas); err != nil {
fail("validate registry", err)
}
}
// Compute and write fields for each ReportDefinition in |config_datas|.
//
// TODO(https://fxbug.dev/278932979): update this comment once Poisson encoding parameters are
// populated by the registry parser.
if err := config_parser.PopulatePrivacyParams(config_datas); err != nil {
fail("populate privacy parameters", err)
}
// Merge the list of project configs in a single config.CobaltRegistry.
c := config_parser.MergeConfigs(config_datas)
filtered := proto.Clone(&c).(*config.CobaltRegistry)
// Write the registry depending upon the specified flags.
if err := source_generator.WriteConfigFromFlags(&c, filtered); err != nil {
fail("write generated registry files", err)
glog.Exit(err)
}
os.Exit(0)
}