Add a flag to fail fast if taze can't resolve an import.

PiperOrigin-RevId: 214674612
diff --git a/ts_auto_deps/updater/updater.go b/ts_auto_deps/updater/updater.go
index a866e85..359389c 100644
--- a/ts_auto_deps/updater/updater.go
+++ b/ts_auto_deps/updater/updater.go
@@ -333,7 +333,7 @@
 // updateDeps adds missing dependencies and removes unnecessary dependencies
 // for the targets in the given DependencyReports to the build rules in bld.
 // Returns true if it changed anything in the build file.
-func updateDeps(bld *build.File, reports []*arpb.DependencyReport) (bool, error) {
+func updateDeps(bld *build.File, errorOnUnresolvedImports bool, reports []*arpb.DependencyReport) (bool, error) {
 	// First, check *all* reports on whether they were successful, so that users
 	// get the complete set of errors at once.
 	var errors []AnalysisFailureCause
@@ -401,6 +401,9 @@
 			errMsg := fmt.Sprintf("ERROR in %s: unresolved imports %s.\nMaybe you are missing a "+
 				"'// from ...'' comment, or the target BUILD files are incorrect?\n%s\n",
 				fullTarget, report.UnresolvedImport, strings.Join(report.GetFeedback(), "\n"))
+			if errorOnUnresolvedImports {
+				return false, fmt.Errorf(errMsg)
+			}
 			fmt.Fprintf(os.Stderr, errMsg)
 			fmt.Fprintf(os.Stderr, "Continuing.\n")
 		}
@@ -503,10 +506,10 @@
 
 // updateBUILDAfterBazelAnalyze applies the BUILD file updates that depend on bazel
 // analyze's DependencyReports, most notably updating any rules' deps.
-func (upd *Updater) updateBUILDAfterBazelAnalyze(ctx context.Context, isRoot bool,
+func (upd *Updater) updateBUILDAfterBazelAnalyze(ctx context.Context, isRoot bool, errorOnUnresolvedImports bool,
 	g3root string, buildFilePath string, bld *build.File, reports []*arpb.DependencyReport) (bool, error) {
 	platform.Infof("Updating deps")
-	updatedBuild, err := updateDeps(bld, reports)
+	updatedBuild, err := updateDeps(bld, errorOnUnresolvedImports, reports)
 	if err != nil {
 		return false, err
 	}
@@ -566,6 +569,10 @@
 	// IsRoot indicates that the directory is a project's root directory, so a tsconfig
 	// rule should be created.
 	IsRoot bool
+	// ErrorOnUnresolvedImports indicates to ts_auto_deps that it should fail when it's unable
+	// to resolve the package for an import instead of printing a warning and continuing
+	// assuming the the user manually added an import to their BUILD for it.
+	ErrorOnUnresolvedImports bool
 }
 
 // UpdateBUILD drives the main process of creating/updating the BUILD file
@@ -606,7 +613,7 @@
 		return false, err
 	}
 
-	changedAfterBazelAnalyze, err := upd.updateBUILDAfterBazelAnalyze(ctx, options.IsRoot, g3root, buildFilePath, bld, reports)
+	changedAfterBazelAnalyze, err := upd.updateBUILDAfterBazelAnalyze(ctx, options.IsRoot, options.ErrorOnUnresolvedImports, g3root, buildFilePath, bld, reports)
 	return changed || changedAfterBazelAnalyze, err
 }
 
diff --git a/ts_auto_deps/updater/updater_test.go b/ts_auto_deps/updater/updater_test.go
index a063a03..c8d1e9b 100644
--- a/ts_auto_deps/updater/updater_test.go
+++ b/ts_auto_deps/updater/updater_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"context"
+	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -213,7 +214,7 @@
 		if err != nil {
 			t.Errorf("parse %s after failed: %s", tst.name, err)
 		}
-		changed, err := updateDeps(bld, []*arpb.DependencyReport{report})
+		changed, err := updateDeps(bld, false, []*arpb.DependencyReport{report})
 		if err != nil {
 			t.Errorf("update %s failed: %s", tst.name, err)
 		}
@@ -228,6 +229,45 @@
 	}
 }
 
+func TestUnresolvedImportError(t *testing.T) {
+	report := parseReport(t, `
+			rule: "//foo:bar"
+			unresolved_import: "unresolved/import"`)
+
+	bld, err := build.ParseBuild("foo/BUILD", []byte(`ts_library(
+					name = "bar",
+					srcs = ["hello.ts"],
+			)`))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	tests := []struct {
+		name                     string
+		errorOnUnresolvedImports bool
+		err                      error
+	}{
+		{
+			name:                     "Error",
+			errorOnUnresolvedImports: true,
+			err: fmt.Errorf("ERROR in %s: unresolved imports %s.\nMaybe you are missing a "+
+				"'// from ...'' comment, or the target BUILD files are incorrect?\n\n", "//foo:bar", []string{"unresolved/import"}),
+		},
+		{
+			name:                     "Warn",
+			errorOnUnresolvedImports: false,
+			err:                      nil,
+		},
+	}
+
+	for _, tst := range tests {
+		_, err = updateDeps(bld, tst.errorOnUnresolvedImports, []*arpb.DependencyReport{report})
+		if !reflect.DeepEqual(err, tst.err) {
+			t.Errorf("update %s returned error %s: expected %s", tst.name, err, tst.err)
+		}
+	}
+}
+
 func TestDottedCall(t *testing.T) {
 	// Repro for a crash, b/35389044
 	buildText := `foo.bar("baz")`