blob: 0e0a3441f459d872b525feae91fc05419ee2cd6f [file] [log] [blame]
// Copyright 2020 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 main
import (
"context"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"github.com/google/subcommands"
"go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto"
"go.fuchsia.dev/fuchsia/tools/lib/logger"
"go.fuchsia.dev/fuchsia/tools/lib/runner"
)
type subprocessRunner interface {
Run(ctx context.Context, cmd []string, stdout, stderr io.Writer) error
}
type SetCommand struct {
staticSpecPath string
contextSpecPath string
}
func (*SetCommand) Name() string { return "set" }
func (*SetCommand) Synopsis() string { return "runs gn gen with args based on the input specs." }
func (*SetCommand) Usage() string {
return `
fint set -context <path> -static <path>
flags:
`
}
func (c *SetCommand) SetFlags(f *flag.FlagSet) {
f.StringVar(&c.staticSpecPath, "static", "", "path to a Static .textproto")
f.StringVar(&c.contextSpecPath, "context", "", "path to a Context .textproto")
}
func (c *SetCommand) Execute(ctx context.Context, _ *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
if c.staticSpecPath == "" || c.contextSpecPath == "" {
logger.Errorf(ctx, "-static and -context flags are required")
return subcommands.ExitUsageError
}
if err := c.run(ctx); err != nil {
logger.Errorf(ctx, err.Error())
return subcommands.ExitFailure
}
return subcommands.ExitSuccess
}
func (c *SetCommand) run(ctx context.Context) error {
logger.Debugf(ctx, "static spec path: %s", c.staticSpecPath)
logger.Debugf(ctx, "context spec path: %s", c.contextSpecPath)
bytes, err := ioutil.ReadFile(c.staticSpecPath)
if err != nil {
return err
}
if _, err = parseStatic(string(bytes)); err != nil {
return err
}
bytes, err = ioutil.ReadFile(c.contextSpecPath)
if err != nil {
return err
}
contextSpec, err := parseContext(string(bytes))
if err != nil {
return err
}
platform, err := getPlatform()
if err != nil {
return err
}
runner := &runner.SubprocessRunner{}
return runGen(ctx, runner, contextSpec, platform)
}
func runGen(ctx context.Context, runner subprocessRunner, contextSpec *proto.Context, platform string) error {
gnPath := filepath.Join(contextSpec.CheckoutDir, "prebuilt", "third_party", "gn", platform, "gn")
genCmd := []string{
gnPath, "gen",
contextSpec.BuildDir,
"--check=system",
"--fail-on-unused-args",
}
if err := runner.Run(ctx, genCmd, os.Stdout, os.Stderr); err != nil {
return fmt.Errorf("error running gn gen: %w", err)
}
return nil
}
func getPlatform() (string, error) {
os, ok := map[string]string{
"windows": "win",
"darwin": "mac",
"linux": "linux",
}[runtime.GOOS]
if !ok {
return "", fmt.Errorf("unsupported GOOS %q", runtime.GOOS)
}
arch, ok := map[string]string{
"amd64": "x64",
"arm64": "arm64",
}[runtime.GOARCH]
if !ok {
return "", fmt.Errorf("unsupported GOARCH %q", runtime.GOARCH)
}
return fmt.Sprintf("%s-%s", os, arch), nil
}