[fint] Expose Set() as a library function
I'm writing a new version of `fx set` in Go that will consume fint as a
library, instead of invoking the fint executable. Go doesn't allow
imports of main packages, so I have to move the `fint set`
implementation details into a separate library package.
This will require some changes to our Copybara configs, recipes.git, and
integration.git to reflect the new proto paths.
Bug: 68465
Change-Id: If78bf2884287143bbb5b6c49e5f697006d816644
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/475875
Reviewed-by: Gary Boone <gboone@google.com>
Commit-Queue: Oliver Newman <olivernewman@google.com>
diff --git a/tools/integration/BUILD.gn b/tools/integration/BUILD.gn
index ab1c6ca..250c6b8 100644
--- a/tools/integration/BUILD.gn
+++ b/tools/integration/BUILD.gn
@@ -16,6 +16,7 @@
deps = [
"//tools/integration/cmd/fint:tests",
+ "//tools/integration/fint:tests",
"//tools/integration/testsharder:testsharder_tests",
]
}
diff --git a/tools/integration/cmd/fint/BUILD.gn b/tools/integration/cmd/fint/BUILD.gn
index d2e20b5..f8c8012 100644
--- a/tools/integration/cmd/fint/BUILD.gn
+++ b/tools/integration/cmd/fint/BUILD.gn
@@ -8,61 +8,24 @@
import("//build/testing/golden_file.gni")
import("//third_party/protobuf/proto_library.gni")
-go_library("proto_lib") {
- source_dir = "proto"
- sources = [
- "context.pb.go",
- "set_artifacts.pb.go",
- "static.pb.go",
- ]
- deps = [ "//third_party/golibs:github.com/golang/protobuf" ]
-}
-
-go_library("filetype_lib") {
- sources = [
- "filetype/filetype.go",
- "filetype/filetype_test.go",
- ]
-}
-
-go_test("filetype_tests") {
- gopackages = [ "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/filetype" ]
- deps = [ ":filetype_lib" ]
-}
-
go_library("fint_lib") {
sources = [
- "fint_test.go",
"main.go",
"parse.go",
+ "parse_test.go",
"set.go",
- "set_test.go",
- "should_build.go",
- "should_build_test.go",
]
deps = [
- ":filetype_lib",
- ":proto_lib",
"//third_party/golibs:github.com/golang/protobuf",
- "//third_party/golibs:github.com/google/go-cmp",
"//third_party/golibs:github.com/google/subcommands",
+ "//tools/integration/fint:fint_lib",
+ "//tools/integration/fint:proto_lib",
"//tools/lib/color",
"//tools/lib/command",
"//tools/lib/jsonutil",
"//tools/lib/logger",
"//tools/lib/osmisc",
- "//tools/lib/runner",
- ]
-}
-
-# This target encompasses all generated proto files, and is intended for use by
-# the update.sh script to avoid needing to specify all the protos again there.
-group("protos") {
- deps = [
- ":context",
- ":set_artifacts",
- ":static",
]
}
@@ -76,65 +39,7 @@
deps = [ ":fint_lib" ]
}
-proto_library("context") {
- sources = [ "proto/context.proto" ]
- generate_cc = false
- generate_go = true
- generate_python = false
-}
-
-proto_library("static") {
- sources = [ "proto/static.proto" ]
- generate_cc = false
- generate_descriptor_set = true
- generate_go = true
- generate_python = false
-}
-
-proto_library("set_artifacts") {
- sources = [ "proto/set_artifacts.proto" ]
- generate_cc = false
- generate_go = true
- generate_python = false
-}
-
-golden_file("context_pb_go_diff") {
- current = "${root_gen_dir}/go-proto-gen/src/tools/integration/cmd/fint/proto/context.pb.go"
- golden = "proto/context.pb.go"
- deps = [ ":context" ]
- warn_on_changes = false
-}
-
-golden_file("static_pb_go_diff") {
- current = "${root_gen_dir}/go-proto-gen/src/tools/integration/cmd/fint/proto/static.pb.go"
- golden = "proto/static.pb.go"
- deps = [ ":static" ]
- warn_on_changes = false
-}
-
-golden_file("set_artifacts_pb_go_diff") {
- current = "${root_gen_dir}/go-proto-gen/src/tools/integration/cmd/fint/proto/set_artifacts.pb.go"
- golden = "proto/set_artifacts.pb.go"
- deps = [ ":set_artifacts" ]
- warn_on_changes = false
-}
-
-golden_file("static_desc_pb_diff") {
- current = "${target_out_dir}/static.desc.pb"
- golden = "proto/static.desc.pb"
- deps = [ ":static" ]
- warn_on_changes = false
-}
-
group("tests") {
testonly = true
- deps = [
- # The diff rules aren't really tests, but we want to ensure they're run in CQ.
- ":context_pb_go_diff",
- ":filetype_tests",
- ":fint_tests",
- ":set_artifacts_pb_go_diff",
- ":static_desc_pb_diff",
- ":static_pb_go_diff",
- ]
+ deps = [ ":fint_tests" ]
}
diff --git a/tools/integration/cmd/fint/parse.go b/tools/integration/cmd/fint/parse.go
index 96db3d9..63b8f20 100644
--- a/tools/integration/cmd/fint/parse.go
+++ b/tools/integration/cmd/fint/parse.go
@@ -6,7 +6,7 @@
import (
"github.com/golang/protobuf/proto"
- fintpb "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto"
+ fintpb "go.fuchsia.dev/fuchsia/tools/integration/fint/proto"
)
func parseStatic(text string) (*fintpb.Static, error) {
diff --git a/tools/integration/cmd/fint/fint_test.go b/tools/integration/cmd/fint/parse_test.go
similarity index 100%
rename from tools/integration/cmd/fint/fint_test.go
rename to tools/integration/cmd/fint/parse_test.go
diff --git a/tools/integration/cmd/fint/proto/examples/empty.textproto b/tools/integration/cmd/fint/proto/examples/empty.textproto
deleted file mode 100644
index e69de29..0000000
--- a/tools/integration/cmd/fint/proto/examples/empty.textproto
+++ /dev/null
diff --git a/tools/integration/cmd/fint/proto/examples/x64-release.textproto b/tools/integration/cmd/fint/proto/examples/x64-release.textproto
deleted file mode 100644
index 0d3d087..0000000
--- a/tools/integration/cmd/fint/proto/examples/x64-release.textproto
+++ /dev/null
@@ -1,11 +0,0 @@
-optimize: RELEASE
-board: "qemu"
-product: "workstation"
-exclude_images: false
-ninja_targets: "default"
-include_host_tests: false
-target_arch: X64
-enforce_size_limits: false
-collect_metrics: false
-include_archives: false
-skip_if_unaffected: true
diff --git a/tools/integration/cmd/fint/proto/update.sh b/tools/integration/cmd/fint/proto/update.sh
deleted file mode 100755
index 24a4a30..0000000
--- a/tools/integration/cmd/fint/proto/update.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-
-# 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.
-
-# This script compiles the .proto files and copies the compiled versions
-# from the build dir back to the source tree. It should be run whenever
-# the .proto files are modified.
-
-set -o errexit
-set -o pipefail
-
-# cd to fuchsia checkout root.
-cd "$( dirname "${BASH_SOURCE[0]}" )/../../../../.."
-
-scripts/fx set core.x64 --with //tools/integration/cmd/fint:protos
-scripts/fx ninja -C out/default tools/integration/cmd/fint:protos
-
-cp out/default/gen/go-proto-gen/src/tools/integration/cmd/fint/proto/*.pb.go \
- tools/integration/cmd/fint/proto/
-cp out/default/obj/tools/integration/cmd/fint/*.desc.pb \
- tools/integration/cmd/fint/proto/
diff --git a/tools/integration/cmd/fint/set.go b/tools/integration/cmd/fint/set.go
index 596b698..de40b71 100644
--- a/tools/integration/cmd/fint/set.go
+++ b/tools/integration/cmd/fint/set.go
@@ -5,24 +5,19 @@
package main
import (
- "bytes"
"context"
"flag"
"fmt"
- "io"
"io/ioutil"
"os"
"path/filepath"
- "runtime"
- "sort"
- "strings"
"github.com/golang/protobuf/jsonpb"
"github.com/google/subcommands"
- fintpb "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto"
+ "go.fuchsia.dev/fuchsia/tools/integration/fint"
+ fintpb "go.fuchsia.dev/fuchsia/tools/integration/fint/proto"
"go.fuchsia.dev/fuchsia/tools/lib/logger"
"go.fuchsia.dev/fuchsia/tools/lib/osmisc"
- "go.fuchsia.dev/fuchsia/tools/lib/runner"
)
const (
@@ -41,10 +36,6 @@
artifactsManifest = "set_artifacts.json"
)
-type subprocessRunner interface {
- Run(ctx context.Context, cmd []string, stdout, stderr io.Writer) error
-}
-
type SetCommand struct {
staticSpecPath string
contextSpecPath string
@@ -117,13 +108,7 @@
}
}
- platform, err := getPlatform()
- if err != nil {
- return err
- }
-
- runner := &runner.SubprocessRunner{}
- artifacts, runErr := runSteps(ctx, runner, staticSpec, contextSpec, platform)
+ artifacts, setErr := fint.Set(ctx, staticSpec, contextSpec)
if contextSpec.ArtifactDir != "" {
f, err := osmisc.CreateFile(filepath.Join(contextSpec.ArtifactDir, artifactsManifest))
@@ -137,7 +122,7 @@
}
}
- return runErr
+ return setErr
}
func defaultContextSpec() (*fintpb.Context, error) {
@@ -150,277 +135,3 @@
BuildDir: filepath.Join(checkoutDir, "out", "default"),
}, nil
}
-
-// runSteps runs `gn gen` along with any post-processing steps, and returns a
-// SetArtifacts object containing metadata produced by GN and post-processing.
-func runSteps(
- ctx context.Context,
- runner subprocessRunner,
- staticSpec *fintpb.Static,
- contextSpec *fintpb.Context,
- platform string,
-) (*fintpb.SetArtifacts, error) {
- gnPath := filepath.Join(contextSpec.CheckoutDir, "prebuilt", "third_party", "gn", platform, "gn")
- artifacts := &fintpb.SetArtifacts{}
- genArgs, err := genArgs(staticSpec, contextSpec, platform)
- if err != nil {
- return nil, err
- }
- if contextSpec.ArtifactDir != "" {
- artifacts.GnTracePath = filepath.Join(contextSpec.ArtifactDir, "gn_trace.json")
- }
- genStdout, err := runGen(ctx, runner, staticSpec, contextSpec, gnPath, artifacts.GnTracePath, genArgs)
- if err != nil {
- artifacts.FailureSummary = genStdout
- return artifacts, err
- }
- if staticSpec.SkipIfUnaffected {
- var changedFiles []string
- for _, f := range contextSpec.ChangedFiles {
- changedFiles = append(changedFiles, f.Path)
- }
- sb, err := shouldBuild(ctx, runner, contextSpec.BuildDir, contextSpec.CheckoutDir, gnPath, changedFiles)
- if err != nil {
- return artifacts, err
- }
- artifacts.SkipBuild = !sb
- }
- return artifacts, err
-}
-
-func runGen(
- ctx context.Context,
- runner subprocessRunner,
- staticSpec *fintpb.Static,
- contextSpec *fintpb.Context,
- gnPath string,
- gnTracePath string,
- args []string,
-) (genStdout string, err error) {
- genCmd := []string{
- gnPath, "gen",
- contextSpec.BuildDir,
- "--check=system",
- "--fail-on-unused-args",
- }
-
- if gnTracePath != "" {
- genCmd = append(genCmd, fmt.Sprintf("--tracelog=%s", gnTracePath))
- }
- if staticSpec.GenerateCompdb {
- genCmd = append(genCmd, "--export-compile-commands")
- }
- if staticSpec.GenerateIde {
- genCmd = append(genCmd, "--ide=json")
- }
-
- genCmd = append(genCmd, fmt.Sprintf("--args=%s", strings.Join(args, " ")))
-
- // When `gn gen` fails, it outputs a brief helpful error message to stdout.
- var stdoutBuf bytes.Buffer
- if err := runner.Run(ctx, genCmd, io.MultiWriter(&stdoutBuf, os.Stdout), os.Stderr); err != nil {
- return stdoutBuf.String(), fmt.Errorf("error running gn gen: %w", err)
- }
- return stdoutBuf.String(), 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
-}
-
-func genArgs(staticSpec *fintpb.Static, contextSpec *fintpb.Context, platform string) ([]string, error) {
- // GN variables to set via args (mapping from variable name to value).
- vars := make(map[string]interface{})
- // GN list variables to which we want to append via args (mapping from
- // variable name to list of values to append).
- appends := make(map[string][]string)
- // GN targets to import.
- var imports []string
-
- if staticSpec.TargetArch == fintpb.Static_ARCH_UNSPECIFIED {
- return nil, fmt.Errorf("target_arch is unspecified or invalid")
- }
- vars["target_cpu"] = strings.ToLower(staticSpec.TargetArch.String())
-
- if staticSpec.Optimize == fintpb.Static_OPTIMIZE_UNSPECIFIED {
- return nil, fmt.Errorf("optimize is unspecified or invalid")
- }
- vars["is_debug"] = staticSpec.Optimize == fintpb.Static_DEBUG
-
- if contextSpec.ClangToolchainDir != "" {
- if staticSpec.UseGoma {
- return nil, fmt.Errorf("goma is not supported for builds using a custom clang toolchain")
- }
- vars["clang_prefix"] = filepath.Join(contextSpec.ClangToolchainDir, "bin")
- }
- if contextSpec.GccToolchainDir != "" {
- if staticSpec.UseGoma {
- return nil, fmt.Errorf("goma is not supported for builds using a custom gcc toolchain")
- }
- vars["zircon_extra_args.gcc_tool_dir"] = filepath.Join(contextSpec.GccToolchainDir, "bin")
- }
- if contextSpec.RustToolchainDir != "" {
- vars["rustc_prefix"] = filepath.Join(contextSpec.RustToolchainDir, "bin")
- }
-
- vars["use_goma"] = staticSpec.UseGoma
- if staticSpec.UseGoma {
- vars["goma_dir"] = filepath.Join(
- contextSpec.CheckoutDir, "prebuilt", "third_party", "goma", platform,
- )
- }
-
- if staticSpec.Product != "" {
- basename := filepath.Base(staticSpec.Product)
- vars["build_info_product"] = strings.Split(basename, ".")[0]
- imports = append(imports, staticSpec.Product)
- }
-
- if staticSpec.Board != "" {
- basename := filepath.Base(staticSpec.Board)
- vars["build_info_board"] = strings.Split(basename, ".")[0]
- imports = append(imports, staticSpec.Board)
- }
-
- if contextSpec.SdkId != "" {
- vars["sdk_id"] = contextSpec.SdkId
- vars["build_sdk_archives"] = true
- }
-
- if contextSpec.ReleaseVersion != "" {
- vars["build_info_version"] = contextSpec.ReleaseVersion
- }
-
- if staticSpec.TestDurationsFile != "" {
- testDurationsFile := staticSpec.TestDurationsFile
- exists, err := osmisc.FileExists(filepath.Join(contextSpec.CheckoutDir, testDurationsFile))
- if err != nil {
- return nil, fmt.Errorf("failed to check if TestDurationsFile exists: %w", err)
- }
- if !exists {
- testDurationsFile = staticSpec.DefaultTestDurationsFile
- }
- vars["test_durations_file"] = testDurationsFile
- }
-
- for varName, packages := range map[string][]string{
- "base_package_labels": staticSpec.BasePackages,
- "cache_package_labels": staticSpec.CachePackages,
- "universe_package_labels": staticSpec.UniversePackages,
- } {
- if len(packages) == 0 {
- continue
- }
- // If product is set, append to the corresponding list variable instead
- // of overwriting it to avoid overwriting any packages set in the
- // imported product file.
- // TODO(olivernewman): Is it safe to always append whether or not
- // product is set?
- if staticSpec.Product == "" {
- vars[varName] = packages
- } else {
- appends[varName] = packages
- }
- }
-
- if len(staticSpec.Variants) != 0 {
- vars["select_variant"] = staticSpec.Variants
- if contains(staticSpec.Variants, "thinlto") {
- vars["thinlto_cache_dir"] = filepath.Join(contextSpec.CacheDir, "thinlto")
- }
- }
-
- var normalArgs []string
- var importArgs []string
- for _, arg := range staticSpec.GnArgs {
- if strings.HasPrefix(arg, "import(") {
- importArgs = append(importArgs, arg)
- } else {
- normalArgs = append(normalArgs, arg)
- }
- }
-
- for k, v := range vars {
- normalArgs = append(normalArgs, fmt.Sprintf("%s=%s", k, toGNValue(v)))
- }
- for k, v := range appends {
- normalArgs = append(normalArgs, fmt.Sprintf("%s+=%s", k, toGNValue(v)))
- }
- sort.Strings(normalArgs)
-
- for _, p := range imports {
- importArgs = append(importArgs, fmt.Sprintf(`import("//%s")`, p))
- }
- sort.Strings(importArgs)
-
- var finalArgs []string
-
- // Ensure that imports come before args that set or modify variables, as
- // otherwise the imported files might blindly redefine variables set or
- // modified by other arguments.
- finalArgs = append(finalArgs, importArgs...)
- // Initialize `zircon_extra_args` before any variable-setting args, so that
- // it's safe for subsequent args to do things like `zircon_extra_args.foo =
- // "bar"` without worrying about initializing zircon_extra_args if it hasn't
- // yet been defined. But do it after all imports in case one of the imported
- // files sets `zircon_extra_args`.
- finalArgs = append(finalArgs, "if (!defined(zircon_extra_args)) { zircon_extra_args = {} }")
- finalArgs = append(finalArgs, normalArgs...)
- return finalArgs, nil
-}
-
-// toGNValue converts a Go value to a string representation of the corresponding
-// GN value by inspecting the Go value's type. This makes the logic to set GN
-// args more readable and less error-prone, with no need for patterns like
-// fmt.Sprintf(`"%s"`) repeated everywhere.
-//
-// For example:
-// - toGNValue(true) => `true`
-// - toGNValue("foo") => `"foo"` (a string containing literal double-quotes)
-// - toGNValue([]string{"foo", "bar"}) => `["foo","bar"]`
-func toGNValue(x interface{}) string {
- switch val := x.(type) {
- case bool:
- return fmt.Sprintf("%v", val)
- case string:
- // Apply double-quotes to strings, but not to GN scopes like
- // {variant="asan-fuzzer" target_type=["fuzzed_executable"]}
- if strings.HasPrefix(val, "{") && strings.HasSuffix(val, "}") {
- return val
- }
- return fmt.Sprintf(`"%s"`, val)
- case []string:
- var values []string
- for _, element := range val {
- values = append(values, toGNValue(element))
- }
- return fmt.Sprintf("[%s]", strings.Join(values, ","))
- default:
- panic(fmt.Sprintf("unsupported arg value type %T", val))
- }
-}
-
-func contains(items []string, target string) bool {
- for _, item := range items {
- if item == target {
- return true
- }
- }
- return false
-}
diff --git a/tools/integration/fint/BUILD.gn b/tools/integration/fint/BUILD.gn
new file mode 100644
index 0000000..5e9ec46
--- /dev/null
+++ b/tools/integration/fint/BUILD.gn
@@ -0,0 +1,133 @@
+# 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.
+
+import("//build/go/go_binary.gni")
+import("//build/go/go_library.gni")
+import("//build/go/go_test.gni")
+import("//build/testing/golden_file.gni")
+import("//third_party/protobuf/proto_library.gni")
+
+go_library("proto_lib") {
+ source_dir = "proto"
+ sources = [
+ "context.pb.go",
+ "set_artifacts.pb.go",
+ "static.pb.go",
+ ]
+ deps = [ "//third_party/golibs:github.com/golang/protobuf" ]
+}
+
+go_library("filetype_lib") {
+ sources = [
+ "filetype/filetype.go",
+ "filetype/filetype_test.go",
+ ]
+}
+
+go_test("filetype_tests") {
+ gopackages = [ "go.fuchsia.dev/fuchsia/tools/integration/fint/filetype" ]
+ deps = [ ":filetype_lib" ]
+}
+
+go_library("fint_lib") {
+ sources = [
+ "common.go",
+ "set.go",
+ "set_test.go",
+ "should_build.go",
+ "should_build_test.go",
+ ]
+
+ deps = [
+ ":filetype_lib",
+ ":proto_lib",
+ "//third_party/golibs:github.com/golang/protobuf",
+ "//third_party/golibs:github.com/google/go-cmp",
+ "//third_party/golibs:github.com/google/subcommands",
+ "//tools/lib/color",
+ "//tools/lib/command",
+ "//tools/lib/jsonutil",
+ "//tools/lib/logger",
+ "//tools/lib/osmisc",
+ "//tools/lib/runner",
+ ]
+}
+
+# This target encompasses all generated proto files, and is intended for use by
+# the update.sh script to avoid needing to specify all the protos again there.
+group("protos") {
+ deps = [
+ ":context",
+ ":set_artifacts",
+ ":static",
+ ]
+}
+
+go_test("fint_lib_tests") {
+ gopackages = [ "go.fuchsia.dev/fuchsia/tools/integration/fint" ]
+ deps = [ ":fint_lib" ]
+}
+
+proto_library("context") {
+ sources = [ "proto/context.proto" ]
+ generate_cc = false
+ generate_go = true
+ generate_python = false
+}
+
+proto_library("static") {
+ sources = [ "proto/static.proto" ]
+ generate_cc = false
+ generate_descriptor_set = true
+ generate_go = true
+ generate_python = false
+}
+
+proto_library("set_artifacts") {
+ sources = [ "proto/set_artifacts.proto" ]
+ generate_cc = false
+ generate_go = true
+ generate_python = false
+}
+
+golden_file("context_pb_go_diff") {
+ current = "${root_gen_dir}/go-proto-gen/src/tools/integration/fint/proto/context.pb.go"
+ golden = "proto/context.pb.go"
+ deps = [ ":context" ]
+ warn_on_changes = false
+}
+
+golden_file("static_pb_go_diff") {
+ current = "${root_gen_dir}/go-proto-gen/src/tools/integration/fint/proto/static.pb.go"
+ golden = "proto/static.pb.go"
+ deps = [ ":static" ]
+ warn_on_changes = false
+}
+
+golden_file("set_artifacts_pb_go_diff") {
+ current = "${root_gen_dir}/go-proto-gen/src/tools/integration/fint/proto/set_artifacts.pb.go"
+ golden = "proto/set_artifacts.pb.go"
+ deps = [ ":set_artifacts" ]
+ warn_on_changes = false
+}
+
+golden_file("static_desc_pb_diff") {
+ current = "${target_out_dir}/static.desc.pb"
+ golden = "proto/static.desc.pb"
+ deps = [ ":static" ]
+ warn_on_changes = false
+}
+
+group("tests") {
+ testonly = true
+ deps = [
+ # The diff rules aren't really tests, but we want to ensure they're run in CQ.
+ ":context_pb_go_diff",
+ ":filetype_tests",
+ ":fint_lib_tests",
+ ":set_artifacts_pb_go_diff",
+ ":static_desc_pb_diff",
+ ":static_pb_go_diff",
+ ]
+}
diff --git a/tools/integration/fint/common.go b/tools/integration/fint/common.go
new file mode 100644
index 0000000..d5115e4
--- /dev/null
+++ b/tools/integration/fint/common.go
@@ -0,0 +1,14 @@
+// Copyright 2021 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 fint
+
+import (
+ "context"
+ "io"
+)
+
+type subprocessRunner interface {
+ Run(ctx context.Context, cmd []string, stdout, stderr io.Writer) error
+}
diff --git a/tools/integration/cmd/fint/filetype/filetype.go b/tools/integration/fint/filetype/filetype.go
similarity index 100%
rename from tools/integration/cmd/fint/filetype/filetype.go
rename to tools/integration/fint/filetype/filetype.go
diff --git a/tools/integration/cmd/fint/filetype/filetype_test.go b/tools/integration/fint/filetype/filetype_test.go
similarity index 100%
rename from tools/integration/cmd/fint/filetype/filetype_test.go
rename to tools/integration/fint/filetype/filetype_test.go
diff --git a/tools/integration/cmd/fint/proto/README.md b/tools/integration/fint/proto/README.md
similarity index 100%
rename from tools/integration/cmd/fint/proto/README.md
rename to tools/integration/fint/proto/README.md
diff --git a/tools/integration/cmd/fint/proto/context.pb.go b/tools/integration/fint/proto/context.pb.go
similarity index 97%
rename from tools/integration/cmd/fint/proto/context.pb.go
rename to tools/integration/fint/proto/context.pb.go
index 9ab1014..332ed1f 100644
--- a/tools/integration/cmd/fint/proto/context.pb.go
+++ b/tools/integration/fint/proto/context.pb.go
@@ -242,12 +242,11 @@
0x64, 0x69, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x75, 0x73, 0x74, 0x54,
0x6f, 0x6f, 0x6c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x69, 0x72, 0x1a, 0x21, 0x0a, 0x0b, 0x43,
0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
- 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x39,
- 0x5a, 0x37, 0x67, 0x6f, 0x2e, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76,
+ 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x35,
+ 0x5a, 0x33, 0x67, 0x6f, 0x2e, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76,
0x2f, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x69,
- 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66,
- 0x69, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x33,
+ 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x69, 0x6e, 0x74, 0x2f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/tools/integration/cmd/fint/proto/context.proto b/tools/integration/fint/proto/context.proto
similarity index 94%
rename from tools/integration/cmd/fint/proto/context.proto
rename to tools/integration/fint/proto/context.proto
index 96c3b37..5eb9db7 100644
--- a/tools/integration/cmd/fint/proto/context.proto
+++ b/tools/integration/fint/proto/context.proto
@@ -6,7 +6,7 @@
package fint;
-option go_package = "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto";
+option go_package = "go.fuchsia.dev/fuchsia/tools/integration/fint/proto";
// Context contains all of the dynamic configuration values for building
// Fuchsia. These values are context-dependent in that they vary based on git
diff --git a/tools/integration/cmd/fint/proto/set_artifacts.pb.go b/tools/integration/fint/proto/set_artifacts.pb.go
similarity index 95%
rename from tools/integration/cmd/fint/proto/set_artifacts.pb.go
rename to tools/integration/fint/proto/set_artifacts.pb.go
index d3d9465..586da74 100644
--- a/tools/integration/cmd/fint/proto/set_artifacts.pb.go
+++ b/tools/integration/fint/proto/set_artifacts.pb.go
@@ -112,11 +112,11 @@
0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x67, 0x6e, 0x54,
0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6b, 0x69, 0x70,
0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x6b,
- 0x69, 0x70, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x6f, 0x2e, 0x66, 0x75,
+ 0x69, 0x70, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x6f, 0x2e, 0x66, 0x75,
0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69,
0x61, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x69, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/tools/integration/cmd/fint/proto/set_artifacts.proto b/tools/integration/fint/proto/set_artifacts.proto
similarity index 90%
rename from tools/integration/cmd/fint/proto/set_artifacts.proto
rename to tools/integration/fint/proto/set_artifacts.proto
index 1b99bda..616e6a2 100644
--- a/tools/integration/cmd/fint/proto/set_artifacts.proto
+++ b/tools/integration/fint/proto/set_artifacts.proto
@@ -6,7 +6,7 @@
package fint;
-option go_package = "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto";
+option go_package = "go.fuchsia.dev/fuchsia/tools/integration/fint/proto";
// SetArtifacts contains information about the manifests and other metadata
// produced by `fint set`.
diff --git a/tools/integration/cmd/fint/proto/static.desc.pb b/tools/integration/fint/proto/static.desc.pb
similarity index 91%
rename from tools/integration/cmd/fint/proto/static.desc.pb
rename to tools/integration/fint/proto/static.desc.pb
index dcd6f20..6e5d10c 100644
--- a/tools/integration/cmd/fint/proto/static.desc.pb
+++ b/tools/integration/fint/proto/static.desc.pb
Binary files differ
diff --git a/tools/integration/cmd/fint/proto/static.pb.go b/tools/integration/fint/proto/static.pb.go
similarity index 98%
rename from tools/integration/cmd/fint/proto/static.pb.go
rename to tools/integration/fint/proto/static.pb.go
index 1a55494..efea8e6 100644
--- a/tools/integration/cmd/fint/proto/static.pb.go
+++ b/tools/integration/fint/proto/static.pb.go
@@ -412,11 +412,11 @@
0x0a, 0x07, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x02, 0x22, 0x30, 0x0a, 0x04, 0x41,
0x72, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x52, 0x43, 0x48, 0x5f, 0x55, 0x4e, 0x53, 0x50,
0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x52, 0x4d,
- 0x36, 0x34, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x36, 0x34, 0x10, 0x02, 0x42, 0x39, 0x5a,
- 0x37, 0x67, 0x6f, 0x2e, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x2f,
+ 0x36, 0x34, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x36, 0x34, 0x10, 0x02, 0x42, 0x35, 0x5a,
+ 0x33, 0x67, 0x6f, 0x2e, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x2f,
0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x69, 0x6e,
- 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x69,
- 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x69, 0x6e, 0x74, 0x2f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/tools/integration/cmd/fint/proto/static.proto b/tools/integration/fint/proto/static.proto
similarity index 97%
rename from tools/integration/cmd/fint/proto/static.proto
rename to tools/integration/fint/proto/static.proto
index 70024b3..42354ca 100644
--- a/tools/integration/cmd/fint/proto/static.proto
+++ b/tools/integration/fint/proto/static.proto
@@ -6,7 +6,7 @@
package fint;
-option go_package = "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto";
+option go_package = "go.fuchsia.dev/fuchsia/tools/integration/fint/proto";
// Static contains all of the non-dynamic configuration values for building
// Fuchsia. These values are "static" in the sense that they don't vary
diff --git a/tools/integration/fint/proto/update.sh b/tools/integration/fint/proto/update.sh
new file mode 100755
index 0000000..f1ea54e
--- /dev/null
+++ b/tools/integration/fint/proto/update.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+# 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.
+
+# This script compiles the .proto files and copies the compiled versions
+# from the build dir back to the source tree. It should be run whenever
+# the .proto files are modified.
+
+set -o errexit
+set -o pipefail
+
+# cd to fuchsia checkout root.
+cd "$( dirname "${BASH_SOURCE[0]}" )/../../../.."
+
+scripts/fx set core.x64 --with //tools/integration/fint:protos
+scripts/fx ninja -C out/default tools/integration/fint:protos
+
+cp out/default/gen/go-proto-gen/src/tools/integration/fint/proto/*.pb.go \
+ tools/integration/fint/proto/
+cp out/default/obj/tools/integration/fint/*.desc.pb \
+ tools/integration/fint/proto/
diff --git a/tools/integration/fint/set.go b/tools/integration/fint/set.go
new file mode 100644
index 0000000..b3ea3b0
--- /dev/null
+++ b/tools/integration/fint/set.go
@@ -0,0 +1,307 @@
+// Copyright 2021 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 fint
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strings"
+
+ fintpb "go.fuchsia.dev/fuchsia/tools/integration/fint/proto"
+ "go.fuchsia.dev/fuchsia/tools/lib/osmisc"
+ "go.fuchsia.dev/fuchsia/tools/lib/runner"
+)
+
+// Set runs `gn gen` given a static and context spec. It's intended to be
+// consumed as a library function.
+func Set(ctx context.Context, staticSpec *fintpb.Static, contextSpec *fintpb.Context) (*fintpb.SetArtifacts, error) {
+ platform, err := getPlatform()
+ if err != nil {
+ return nil, err
+ }
+
+ runner := &runner.SubprocessRunner{}
+ return runSteps(ctx, runner, staticSpec, contextSpec, platform)
+}
+
+// runSteps runs `gn gen` along with any post-processing steps, and returns a
+// SetArtifacts object containing metadata produced by GN and post-processing.
+func runSteps(
+ ctx context.Context,
+ runner subprocessRunner,
+ staticSpec *fintpb.Static,
+ contextSpec *fintpb.Context,
+ platform string,
+) (*fintpb.SetArtifacts, error) {
+ gnPath := filepath.Join(contextSpec.CheckoutDir, "prebuilt", "third_party", "gn", platform, "gn")
+ artifacts := &fintpb.SetArtifacts{}
+ genArgs, err := genArgs(staticSpec, contextSpec, platform)
+ if err != nil {
+ return nil, err
+ }
+ if contextSpec.ArtifactDir != "" {
+ artifacts.GnTracePath = filepath.Join(contextSpec.ArtifactDir, "gn_trace.json")
+ }
+ genStdout, err := runGen(ctx, runner, staticSpec, contextSpec, gnPath, artifacts.GnTracePath, genArgs)
+ if err != nil {
+ artifacts.FailureSummary = genStdout
+ return artifacts, err
+ }
+ if staticSpec.SkipIfUnaffected {
+ var changedFiles []string
+ for _, f := range contextSpec.ChangedFiles {
+ changedFiles = append(changedFiles, f.Path)
+ }
+ sb, err := shouldBuild(ctx, runner, contextSpec.BuildDir, contextSpec.CheckoutDir, gnPath, changedFiles)
+ if err != nil {
+ return artifacts, err
+ }
+ artifacts.SkipBuild = !sb
+ }
+ return artifacts, err
+}
+
+func runGen(
+ ctx context.Context,
+ runner subprocessRunner,
+ staticSpec *fintpb.Static,
+ contextSpec *fintpb.Context,
+ gnPath string,
+ gnTracePath string,
+ args []string,
+) (genStdout string, err error) {
+ genCmd := []string{
+ gnPath, "gen",
+ contextSpec.BuildDir,
+ "--check=system",
+ "--fail-on-unused-args",
+ }
+
+ if gnTracePath != "" {
+ genCmd = append(genCmd, fmt.Sprintf("--tracelog=%s", gnTracePath))
+ }
+ if staticSpec.GenerateCompdb {
+ genCmd = append(genCmd, "--export-compile-commands")
+ }
+ if staticSpec.GenerateIde {
+ genCmd = append(genCmd, "--ide=json")
+ }
+
+ genCmd = append(genCmd, fmt.Sprintf("--args=%s", strings.Join(args, " ")))
+
+ // When `gn gen` fails, it outputs a brief helpful error message to stdout.
+ var stdoutBuf bytes.Buffer
+ if err := runner.Run(ctx, genCmd, io.MultiWriter(&stdoutBuf, os.Stdout), os.Stderr); err != nil {
+ return stdoutBuf.String(), fmt.Errorf("error running gn gen: %w", err)
+ }
+ return stdoutBuf.String(), 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
+}
+
+func genArgs(staticSpec *fintpb.Static, contextSpec *fintpb.Context, platform string) ([]string, error) {
+ // GN variables to set via args (mapping from variable name to value).
+ vars := make(map[string]interface{})
+ // GN list variables to which we want to append via args (mapping from
+ // variable name to list of values to append).
+ appends := make(map[string][]string)
+ // GN targets to import.
+ var imports []string
+
+ if staticSpec.TargetArch == fintpb.Static_ARCH_UNSPECIFIED {
+ return nil, fmt.Errorf("target_arch is unspecified or invalid")
+ }
+ vars["target_cpu"] = strings.ToLower(staticSpec.TargetArch.String())
+
+ if staticSpec.Optimize == fintpb.Static_OPTIMIZE_UNSPECIFIED {
+ return nil, fmt.Errorf("optimize is unspecified or invalid")
+ }
+ vars["is_debug"] = staticSpec.Optimize == fintpb.Static_DEBUG
+
+ if contextSpec.ClangToolchainDir != "" {
+ if staticSpec.UseGoma {
+ return nil, fmt.Errorf("goma is not supported for builds using a custom clang toolchain")
+ }
+ vars["clang_prefix"] = filepath.Join(contextSpec.ClangToolchainDir, "bin")
+ }
+ if contextSpec.GccToolchainDir != "" {
+ if staticSpec.UseGoma {
+ return nil, fmt.Errorf("goma is not supported for builds using a custom gcc toolchain")
+ }
+ vars["zircon_extra_args.gcc_tool_dir"] = filepath.Join(contextSpec.GccToolchainDir, "bin")
+ }
+ if contextSpec.RustToolchainDir != "" {
+ vars["rustc_prefix"] = filepath.Join(contextSpec.RustToolchainDir, "bin")
+ }
+
+ vars["use_goma"] = staticSpec.UseGoma
+ if staticSpec.UseGoma {
+ vars["goma_dir"] = filepath.Join(
+ contextSpec.CheckoutDir, "prebuilt", "third_party", "goma", platform,
+ )
+ }
+
+ if staticSpec.Product != "" {
+ basename := filepath.Base(staticSpec.Product)
+ vars["build_info_product"] = strings.Split(basename, ".")[0]
+ imports = append(imports, staticSpec.Product)
+ }
+
+ if staticSpec.Board != "" {
+ basename := filepath.Base(staticSpec.Board)
+ vars["build_info_board"] = strings.Split(basename, ".")[0]
+ imports = append(imports, staticSpec.Board)
+ }
+
+ if contextSpec.SdkId != "" {
+ vars["sdk_id"] = contextSpec.SdkId
+ vars["build_sdk_archives"] = true
+ }
+
+ if contextSpec.ReleaseVersion != "" {
+ vars["build_info_version"] = contextSpec.ReleaseVersion
+ }
+
+ if staticSpec.TestDurationsFile != "" {
+ testDurationsFile := staticSpec.TestDurationsFile
+ exists, err := osmisc.FileExists(filepath.Join(contextSpec.CheckoutDir, testDurationsFile))
+ if err != nil {
+ return nil, fmt.Errorf("failed to check if TestDurationsFile exists: %w", err)
+ }
+ if !exists {
+ testDurationsFile = staticSpec.DefaultTestDurationsFile
+ }
+ vars["test_durations_file"] = testDurationsFile
+ }
+
+ for varName, packages := range map[string][]string{
+ "base_package_labels": staticSpec.BasePackages,
+ "cache_package_labels": staticSpec.CachePackages,
+ "universe_package_labels": staticSpec.UniversePackages,
+ } {
+ if len(packages) == 0 {
+ continue
+ }
+ // If product is set, append to the corresponding list variable instead
+ // of overwriting it to avoid overwriting any packages set in the
+ // imported product file.
+ // TODO(olivernewman): Is it safe to always append whether or not
+ // product is set?
+ if staticSpec.Product == "" {
+ vars[varName] = packages
+ } else {
+ appends[varName] = packages
+ }
+ }
+
+ if len(staticSpec.Variants) != 0 {
+ vars["select_variant"] = staticSpec.Variants
+ if contains(staticSpec.Variants, "thinlto") {
+ vars["thinlto_cache_dir"] = filepath.Join(contextSpec.CacheDir, "thinlto")
+ }
+ }
+
+ var normalArgs []string
+ var importArgs []string
+ for _, arg := range staticSpec.GnArgs {
+ if strings.HasPrefix(arg, "import(") {
+ importArgs = append(importArgs, arg)
+ } else {
+ normalArgs = append(normalArgs, arg)
+ }
+ }
+
+ for k, v := range vars {
+ normalArgs = append(normalArgs, fmt.Sprintf("%s=%s", k, toGNValue(v)))
+ }
+ for k, v := range appends {
+ normalArgs = append(normalArgs, fmt.Sprintf("%s+=%s", k, toGNValue(v)))
+ }
+ sort.Strings(normalArgs)
+
+ for _, p := range imports {
+ importArgs = append(importArgs, fmt.Sprintf(`import("//%s")`, p))
+ }
+ sort.Strings(importArgs)
+
+ var finalArgs []string
+
+ // Ensure that imports come before args that set or modify variables, as
+ // otherwise the imported files might blindly redefine variables set or
+ // modified by other arguments.
+ finalArgs = append(finalArgs, importArgs...)
+ // Initialize `zircon_extra_args` before any variable-setting args, so that
+ // it's safe for subsequent args to do things like `zircon_extra_args.foo =
+ // "bar"` without worrying about initializing zircon_extra_args if it hasn't
+ // yet been defined. But do it after all imports in case one of the imported
+ // files sets `zircon_extra_args`.
+ finalArgs = append(finalArgs, "if (!defined(zircon_extra_args)) { zircon_extra_args = {} }")
+ finalArgs = append(finalArgs, normalArgs...)
+ return finalArgs, nil
+}
+
+// toGNValue converts a Go value to a string representation of the corresponding
+// GN value by inspecting the Go value's type. This makes the logic to set GN
+// args more readable and less error-prone, with no need for patterns like
+// fmt.Sprintf(`"%s"`) repeated everywhere.
+//
+// For example:
+// - toGNValue(true) => `true`
+// - toGNValue("foo") => `"foo"` (a string containing literal double-quotes)
+// - toGNValue([]string{"foo", "bar"}) => `["foo","bar"]`
+func toGNValue(x interface{}) string {
+ switch val := x.(type) {
+ case bool:
+ return fmt.Sprintf("%v", val)
+ case string:
+ // Apply double-quotes to strings, but not to GN scopes like
+ // {variant="asan-fuzzer" target_type=["fuzzed_executable"]}
+ if strings.HasPrefix(val, "{") && strings.HasSuffix(val, "}") {
+ return val
+ }
+ return fmt.Sprintf(`"%s"`, val)
+ case []string:
+ var values []string
+ for _, element := range val {
+ values = append(values, toGNValue(element))
+ }
+ return fmt.Sprintf("[%s]", strings.Join(values, ","))
+ default:
+ panic(fmt.Sprintf("unsupported arg value type %T", val))
+ }
+}
+
+func contains(items []string, target string) bool {
+ for _, item := range items {
+ if item == target {
+ return true
+ }
+ }
+ return false
+}
diff --git a/tools/integration/cmd/fint/set_test.go b/tools/integration/fint/set_test.go
similarity index 99%
rename from tools/integration/cmd/fint/set_test.go
rename to tools/integration/fint/set_test.go
index 781ad1a..2d0d5cd 100644
--- a/tools/integration/cmd/fint/set_test.go
+++ b/tools/integration/fint/set_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package main
+package fint
import (
"context"
@@ -14,7 +14,7 @@
"testing"
"github.com/golang/protobuf/proto"
- fintpb "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/proto"
+ fintpb "go.fuchsia.dev/fuchsia/tools/integration/fint/proto"
"go.fuchsia.dev/fuchsia/tools/lib/osmisc"
)
diff --git a/tools/integration/cmd/fint/should_build.go b/tools/integration/fint/should_build.go
similarity index 98%
rename from tools/integration/cmd/fint/should_build.go
rename to tools/integration/fint/should_build.go
index e5548f8..cf3fdc3 100644
--- a/tools/integration/cmd/fint/should_build.go
+++ b/tools/integration/fint/should_build.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package main
+package fint
import (
"context"
@@ -11,7 +11,7 @@
"os"
"path/filepath"
- "go.fuchsia.dev/fuchsia/tools/integration/cmd/fint/filetype"
+ "go.fuchsia.dev/fuchsia/tools/integration/fint/filetype"
"go.fuchsia.dev/fuchsia/tools/lib/jsonutil"
"go.fuchsia.dev/fuchsia/tools/lib/logger"
)
diff --git a/tools/integration/cmd/fint/should_build_test.go b/tools/integration/fint/should_build_test.go
similarity index 99%
rename from tools/integration/cmd/fint/should_build_test.go
rename to tools/integration/fint/should_build_test.go
index be742a5..f9e7c40 100644
--- a/tools/integration/cmd/fint/should_build_test.go
+++ b/tools/integration/fint/should_build_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package main
+package fint
import (
"context"