Make fidlgen_dart optional

This makes the fidlgen_dart binary optional, and shows an error in the
client if it isn't available. This will unblock deploying fidlbolt
regularly again, since fidlgen_dart isn't in fuchsia.git anymore.

I made the Makefile accept a FIDLBOLT_PATH environment variable to
specify additional search paths for `make run DEPLOYMENT=0`, which I can
use to specify a local path to fidlgen_dart.

I also updated the experimental flags passed to fidlc to match the
current defaults in fuchsia.git.

Change-Id: I1aebf953d3526188fc1cde099d4a1e86d4156e45
Reviewed-on: https://fuchsia-review.googlesource.com/c/fidlbolt/+/955452
Reviewed-by: Ian McKellar <ianloic@google.com>
diff --git a/Makefile b/Makefile
index 4d20d8e..9dda9f5 100644
--- a/Makefile
+++ b/Makefile
@@ -38,7 +38,8 @@
 build_dir := $(if $(patsubst /%,,$(build_dir)),$(FUCHSIA_DIR)/,)$(build_dir)
 bin := $(build_dir)/host_x64$\
 	:$(FUCHSIA_DIR)/prebuilt/third_party/clang/$(host_platform)/bin$\
-	:$(FUCHSIA_DIR)/prebuilt/third_party/rust/$(host_platform)/bin
+	:$(FUCHSIA_DIR)/prebuilt/third_party/rust/$(host_platform)/bin$\
+	$(if $(FIDLBOLT_PATH),:$(FIDLBOLT_PATH),)
 etc := $(FUCHSIA_DIR)
 # TODO(fxbug.dev/72629) Remove banjo.
 fidl := $(FUCHSIA_DIR)/sdk/fidl$\
diff --git a/backend/server.go b/backend/server.go
index 9204527..5c209c0 100644
--- a/backend/server.go
+++ b/backend/server.go
@@ -10,6 +10,7 @@
 	"errors"
 	"fmt"
 	"io/ioutil"
+	"log"
 	"os"
 	"regexp"
 	"strings"
@@ -21,7 +22,10 @@
 	deployment *deployment
 	// External programs used by fidlbolt.
 	fidlFormat, fidlLint, fidlc, fidlgenCpp, fidlgenHlcpp, fidlgenRust,
-	fidlgenGo, fidlgenDart, clangFormat, rustfmt program
+	fidlgenGo, clangFormat, rustfmt program
+	// Optional external programs.
+	fidlgenDart    program
+	hasFidlgenDart bool
 	// External files used by fidlbolt.
 	rustfmtToml string
 	// Cache of FIDL library information.
@@ -72,10 +76,6 @@
 	if err != nil {
 		return nil, err
 	}
-	s.fidlgenDart, err = findProgram("fidlgen_dart", bin)
-	if err != nil {
-		return nil, err
-	}
 	s.clangFormat, err = findProgram("clang-format", bin)
 	if err != nil {
 		return nil, err
@@ -84,6 +84,11 @@
 	if err != nil {
 		return nil, err
 	}
+	s.fidlgenDart, err = findProgram("fidlgen_dart", bin)
+	if err != nil {
+		log.Printf("warning: %s", err)
+		s.hasFidlgenDart = false
+	}
 	s.rustfmtToml, err = findFile("rustfmt.toml", etc)
 	if err != nil {
 		return nil, err
@@ -396,7 +401,7 @@
 		for _, availableArg := range strings.Fields(r.Options.VersionSelection) {
 			args = append(args, "--available", availableArg)
 		}
-		args = append(args, "--experimental", "unknown_interactions")
+		args = append(args, "--experimental", "transitional_allow_list")
 		args = append(args, fileArgs...)
 		run, err := s.fidlc.run(ctx, args...)
 		if err != nil {
@@ -483,6 +488,11 @@
 	if !res.Ok {
 		return res, nil
 	}
+	if r.OutputMode == Dart && !s.hasFidlgenDart {
+		res.Content = "This build of fidlbolt does not include fidlgen_dart"
+		res.Ok = false
+		return res, nil
+	}
 	res.Content, err = s.handleFIDLWithIR(ctx, r, temp, jsonIR, analysis)
 	if err != nil {
 		return response{}, err
diff --git a/prepare_deployment.sh b/prepare_deployment.sh
index b9c47e2..319628c 100755
--- a/prepare_deployment.sh
+++ b/prepare_deployment.sh
@@ -89,7 +89,6 @@
     "fidl-lint"
     "fidlc"
     "fidlgen_cpp"
-    "fidlgen_dart"
     "fidlgen_go"
     "fidlgen_hlcpp"
     "fidlgen_rust"