diff --git a/BUILD.bazel b/BUILD.bazel
index 7f69e55..b0a0051 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -45,8 +45,5 @@
         "//devserver:devserver-windows",
         "//internal:generated_BUILD",
         "//internal:tsc_wrapped",
-        "//ts_auto_deps:ts_auto_deps-darwin",
-        "//ts_auto_deps:ts_auto_deps-linux",
-        "//ts_auto_deps:ts_auto_deps-windows",
     ],
 )
diff --git a/README.md b/README.md
index 41028ad..8b1aceb 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,6 @@
 It contains these utilities:
 
 - `ts_devserver`: a Go library and binary that runs a fast local web server which concatenates JavaScript on-the-fly. It requires inputs in a named module format (module ids must be contained in the file, not inferred from the file's path).
-- `ts_auto_deps`: a Go library and binary which generates `BUILD.bazel` files from TypeScript sources.
 - `tsc_wrapped`: a TypeScript program which wraps the TypeScript compiler, hosting it under a Bazel worker.
 - `tsetse`: a collection of third-party "strictness" checks which we add to the TypeScript compiler.
 - `internal/common/*.bzl`: some Starlark utility code for running the `ts_library` rule.
diff --git a/package.bzl b/package.bzl
index 2e4473d..e1c4bb3 100644
--- a/package.bzl
+++ b/package.bzl
@@ -42,7 +42,7 @@
         sha256 = "f624fe9ca8d51de192655369ac538c420afb7cde16e1ad052554b582fff09287",
     )
 
-    # For building ts_devserver and ts_auto_deps binaries
+    # For building ts_devserver binary
     # See https://github.com/bazelbuild/rules_go#setup for the latest version.
     _maybe(
         http_archive,
@@ -77,15 +77,6 @@
         sha256 = "3c681998538231a2d24d0c07ed5a7658cb72bfb5fd4bf9911157c0e9ac6a2687",
     )
 
-    # ts_auto_deps depends on com_github_bazelbuild_buildtools
-    _maybe(
-        http_archive,
-        name = "com_github_bazelbuild_buildtools",
-        url = "https://github.com/bazelbuild/buildtools/archive/0.19.2.1.zip",
-        strip_prefix = "buildtools-0.19.2.1",
-        sha256 = "9176a7df34dbed2cf5171eb56271868824560364e60644348219f852f593ae79",
-    )
-
 def _maybe(repo_rule, name, **kwargs):
     if not native.existing_rule(name):
         repo_rule(name = name, **kwargs)
diff --git a/ts_auto_deps/BUILD.bazel b/ts_auto_deps/BUILD.bazel
deleted file mode 100644
index b71e8a1..0000000
--- a/ts_auto_deps/BUILD.bazel
+++ /dev/null
@@ -1,48 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["main.go"],
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps",
-    visibility = ["//visibility:private"],
-    deps = [
-        "//ts_auto_deps/platform:go_default_library",
-        "//ts_auto_deps/updater:go_default_library",
-    ],
-)
-
-go_binary(
-    name = "ts_auto_deps_bin",
-    embed = [":go_default_library"],
-    visibility = ["//visibility:public"],
-)
-
-go_binary(
-    name = "ts_auto_deps-darwin",
-    out = "ts_auto_deps-darwin_x64",
-    embed = [":go_default_library"],
-    goarch = "amd64",
-    goos = "darwin",
-    pure = "on",
-    visibility = ["//visibility:public"],
-)
-
-go_binary(
-    name = "ts_auto_deps-linux",
-    out = "ts_auto_deps-linux_x64",
-    embed = [":go_default_library"],
-    goarch = "amd64",
-    goos = "linux",
-    pure = "on",
-    visibility = ["//visibility:public"],
-)
-
-go_binary(
-    name = "ts_auto_deps-windows",
-    out = "ts_auto_deps-win32_x64.exe",
-    embed = [":go_default_library"],
-    goarch = "amd64",
-    goos = "windows",
-    pure = "on",
-    visibility = ["//visibility:public"],
-)
diff --git a/ts_auto_deps/analyze/BUILD.bazel b/ts_auto_deps/analyze/BUILD.bazel
deleted file mode 100644
index 29213ce..0000000
--- a/ts_auto_deps/analyze/BUILD.bazel
+++ /dev/null
@@ -1,37 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "analyze.go",
-        "imports.go",
-        "loader.go",
-    ],
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps/analyze",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//ts_auto_deps/platform:go_default_library",
-        "//ts_auto_deps/proto:go_default_library",
-        "//ts_auto_deps/workspace:go_default_library",
-        "@com_github_bazelbuild_buildtools//build_proto:go_default_library",
-        "@com_github_bazelbuild_buildtools//edit:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = [
-        "analyze_test.go",
-        "imports_test.go",
-        "loader_test.go",
-    ],
-    embed = [":go_default_library"],
-    deps = [
-        "//ts_auto_deps/platform:go_default_library",
-        "//ts_auto_deps/proto:go_default_library",
-        "@com_github_bazelbuild_buildtools//build_proto:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-        "@com_github_kylelemons_godebug//pretty:go_default_library",
-    ],
-)
diff --git a/ts_auto_deps/analyze/analyze.go b/ts_auto_deps/analyze/analyze.go
deleted file mode 100644
index 9e005cc..0000000
--- a/ts_auto_deps/analyze/analyze.go
+++ /dev/null
@@ -1,603 +0,0 @@
-// Package analyze uses bazel query to determine and locate missing imports
-// in TypeScript source files.
-package analyze
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"path/filepath"
-	"regexp"
-	"strings"
-
-	"github.com/bazelbuild/buildtools/edit"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace"
-	"github.com/golang/protobuf/proto"
-
-	appb "github.com/bazelbuild/buildtools/build_proto"
-	arpb "github.com/bazelbuild/rules_typescript/ts_auto_deps/proto"
-)
-
-var (
-	extensions = []string{
-		// '.d.ts' must come before '.ts' to completely remove the '.d.ts'
-		// extension.
-		".d.ts",
-		".ts",
-		".tsx",
-	}
-)
-
-const (
-	// debug enables/disables debug logging. Set to true to have debug statements
-	// print to stdout, set to false to disable debug statements.
-	debug = false
-)
-
-// debugf prints a formatted message prefixed with "DEBUG:" if the debug
-// flag is enabled.
-func debugf(format string, v ...interface{}) {
-	if debug {
-		fmt.Printf(fmt.Sprintf("DEBUG: %s\n", format), v...)
-	}
-}
-
-// TargetLoader provides methods for loading targets from BUILD files.
-type TargetLoader interface {
-	// LoadTargets loads targets from BUILD files associated with labels. A target
-	// is a rule, source file, generated file, package group or environment group.
-	// It returns a mapping from labels to targets or an error, if any occurred.
-	//
-	// A label must be the absolute label associated with a target. For example,
-	// '//foo/bar:baz' is acceptable whereas 'bar:baz' or '//foo/bar' will result
-	// in undefined behavior. TODO(lucassloan): make this an error
-	//
-	// Only returns targets visible to currentPkg. If currentPkg is an empty
-	// string returns all targets regardless of visibility.
-	LoadTargets(currentPkg string, labels []string) (map[string]*appb.Target, error)
-	// LoadRules loads rules from BUILD files associated with labels.
-	// It returns a mapping from labels to rules or an error, if any
-	// occurred.
-	//
-	// A label must be the absolute label associated with a rule. For
-	// example, '//foo/bar:baz' is acceptable whereas 'bar:baz' or '//foo/bar'
-	// will result in undefined behavior.
-	// TODO(lucassloan): make this an error.
-	//
-	// Only returns rules visible to currentPkg. If currentPkg is an empty string
-	// returns all rules regardless of visibility.
-	LoadRules(currentPkg string, labels []string) (map[string]*appb.Rule, error)
-	// LoadImportPaths loads targets from BUILD files associated with import
-	// paths relative to a root directory. It returns a mapping from import
-	// paths to targets or an error, if any occurred.
-	//
-	// An import path is the path present in a TypeScript import statement
-	// resolved relative to the workspace root. For example, an import
-	// statement 'import baz from "../baz.ts"' declared in the TypeScript
-	// source file '//foo/bar.ts' would have the import path of 'baz.ts'. If
-	// no target is found associated with a provided import path, the import
-	// path should be excluded from the returned mapping but an error should
-	// not be returned.
-	//
-	// Only returns rules visible to currentPkg. If currentPkg is an empty string
-	// returns all targets regardless of visibility.
-	LoadImportPaths(ctx context.Context, targetToAnalyze *appb.Rule, currentPkg, root string, paths []string) (map[string]*appb.Rule, error)
-}
-
-// Analyzer uses a BuildLoader to generate dependency reports.
-type Analyzer struct {
-	loader TargetLoader
-}
-
-// New returns a new Analyzer which can be used to generate dependency reports.
-func New(loader TargetLoader) *Analyzer {
-	return &Analyzer{loader: loader}
-}
-
-// Analyze generates a dependency report for each target label in labels.
-//
-// dir is the directory that ts_auto_deps should execute in. Must be a sub-directory
-// of the workspace root.
-func (a *Analyzer) Analyze(ctx context.Context, dir string, labels []string) ([]*arpb.DependencyReport, error) {
-	if len(labels) == 0 {
-		return nil, nil
-	}
-	_, currentPkg, _ := edit.ParseLabel(labels[0])
-	for _, label := range labels {
-		if _, pkg, _ := edit.ParseLabel(label); pkg != currentPkg {
-			return nil, fmt.Errorf("can't analyze targets in different packages")
-		}
-	}
-	root, err := workspace.Root(dir)
-	if err != nil {
-		return nil, err
-	}
-	rules, err := a.loader.LoadRules(currentPkg, labels)
-	if err != nil {
-		return nil, err
-	}
-	resolved, err := a.resolveImportsForTargets(ctx, currentPkg, root, rules)
-	if err != nil {
-		return nil, err
-	}
-	return a.generateReports(labels, resolved)
-}
-
-// resolvedTarget represents a Bazel target and all resolved information.
-type resolvedTarget struct {
-	label string
-	// A map of all existing dependencies on a target at the time of analysis.
-	// The keys are labels and the values are thes loaded target.
-	dependencies map[string]*appb.Rule
-	// A map of source file paths to their imports.
-	imports map[string][]*ts_auto_depsImport
-	// rule is the original rule the target was constructed from.
-	rule *appb.Rule
-	// missingSources are source files which could not be opened on disk.
-	// These are added to the dependency reports and MissingSources.
-	missingSources []string
-	// A map from the labels in the target's srcs to the Targets those
-	// labels refer.
-	sources              map[string]*appb.Target
-	literalSourcePaths   []string
-	generatedSourcePaths []string
-}
-
-// setSources sets the sources on t.  It returns an error if one of the srcs of
-// t's rule isn't in loadedSrcs.  It also sorts the sources into literal and
-// generated sources, setting literalSourcePaths and generatedSourcePaths.
-// Returns an error if all the sources are generated - ts_auto_deps can't read the
-// import statements to determine deps.
-func (t *resolvedTarget) setSources(loadedSrcs map[string]*appb.Target) error {
-	for _, label := range listAttribute(t.rule, "srcs") {
-		src := loadedSrcs[label]
-		if src == nil {
-			return fmt.Errorf("no source found for label %s", label)
-		}
-		t.sources[label] = src
-		if src.GetType() == appb.Target_SOURCE_FILE {
-			t.literalSourcePaths = append(t.literalSourcePaths, labelToPath(label))
-		} else {
-			t.generatedSourcePaths = append(t.generatedSourcePaths, labelToPath(label))
-		}
-	}
-	if len(t.literalSourcePaths) == 0 && len(t.generatedSourcePaths) > 0 {
-		return fmt.Errorf("rule has generated sources - cannot determine dependencies")
-	}
-	return nil
-}
-
-// srcs returns the labels of the sources of t.
-func (t *resolvedTarget) srcs() ([]string, error) {
-	srcs := listAttribute(t.rule, "srcs")
-	if srcs == nil {
-		return nil, fmt.Errorf("target %q missing \"srcs\" attribute", t.label)
-	}
-
-	return srcs, nil
-}
-
-// getAllLiteralSrcPaths returns the file paths of all the non-generated sources
-// of the targets.
-func getAllLiteralSrcPaths(targets map[string]*resolvedTarget) ([]string, error) {
-	var allLiteralSrcPaths []string
-	for _, t := range targets {
-		allLiteralSrcPaths = append(allLiteralSrcPaths, t.literalSourcePaths...)
-	}
-
-	return allLiteralSrcPaths, nil
-}
-
-func (t *resolvedTarget) deps() []string {
-	return listAttribute(t.rule, "deps")
-}
-
-// provides returns whether the resolved target can provide the path provided.
-func (t *resolvedTarget) provides(path string) bool {
-	for _, label := range listAttribute(t.rule, "srcs") {
-		src := t.sources[label]
-		if src.GetType() == appb.Target_SOURCE_FILE {
-			// For literal sources, check the path of the source
-			if labelToPath(label) == path {
-				return true
-			}
-		} else if src.GetType() == appb.Target_RULE {
-			// For generated souces, check against the paths of rule's
-			// outputs
-			for _, genSrc := range src.GetRule().GetRuleOutput() {
-				if labelToPath(genSrc) == path {
-					return true
-				}
-			}
-		}
-	}
-	return false
-}
-
-// newTarget constructs a new target instance from a loaded rule.
-func newResolvedTarget(r *appb.Rule) *resolvedTarget {
-	return &resolvedTarget{
-		label:        r.GetName(),
-		dependencies: make(map[string]*appb.Rule),
-		imports:      make(map[string][]*ts_auto_depsImport),
-		rule:         r,
-		sources:      make(map[string]*appb.Target),
-	}
-}
-
-// resolveImportsForTargets attempts to resolve the imports in the sources of
-// each target in targets.
-func (a *Analyzer) resolveImportsForTargets(ctx context.Context, currentPkg, root string, allTargets map[string]*appb.Rule) (map[string]*resolvedTarget, error) {
-	targets := make(map[string]*resolvedTarget)
-	var allDeps, allSrcs []string
-	for _, t := range allTargets {
-		target := newResolvedTarget(t)
-		targets[target.label] = target
-		srcs, err := target.srcs()
-		if err != nil {
-			return nil, err
-		}
-		allDeps = append(allDeps, target.deps()...)
-		allSrcs = append(allSrcs, srcs...)
-	}
-	deps, err := a.loader.LoadRules(currentPkg, allDeps)
-	if err != nil {
-		return nil, err
-	}
-	// Associate the loaded existing deps with the target or targets which
-	// contained them.
-	for _, t := range targets {
-		for _, dep := range t.deps() {
-			t.dependencies[dep] = deps[dep]
-		}
-	}
-	// load all the sources in the targets, so that literal and generated
-	// targets can be distinguished
-	srcs, err := a.loader.LoadTargets(currentPkg, allSrcs)
-	if err != nil {
-		return nil, err
-	}
-	for _, t := range targets {
-		err := t.setSources(srcs)
-		if err != nil {
-			return nil, err
-		}
-	}
-	// only extract the imports out of the literal sources, since ts_auto_deps can't
-	// see the contents of generated files
-	allLiteralSrcPaths, err := getAllLiteralSrcPaths(targets)
-	if err != nil {
-		return nil, err
-	}
-	imports, errs := extractAllImports(root, allLiteralSrcPaths)
-	for _, err := range errs {
-		// NotExist errors are caught and added to the generated dependency
-		// reports as missing source files. Only errors which are not NotExist
-		// errors should be reported.
-		if !os.IsNotExist(err) {
-			return nil, err
-		}
-	}
-	for _, t := range targets {
-		srcs := t.literalSourcePaths
-		for _, src := range srcs {
-			v, ok := imports[src]
-			if ok {
-				t.imports[src] = v
-			} else {
-				// The source was not found on disk during import extraction.
-				t.missingSources = append(t.missingSources, relativePathLabel(t.label, src))
-			}
-		}
-	}
-	if err := a.resolveImports(ctx, currentPkg, root, targets); err != nil {
-		return nil, err
-	}
-	return targets, nil
-}
-
-// resolveImports finds targets which provide the imported file or library
-// for imports without known targets.
-func (a *Analyzer) resolveImports(ctx context.Context, currentPkg, root string, targets map[string]*resolvedTarget) error {
-	for _, target := range targets {
-		var paths []string
-		needingResolution := make(map[string][]*ts_auto_depsImport)
-		for _, imports := range target.imports {
-		handlingImports:
-			for _, imp := range imports {
-				resolvedPath := imp.resolvedPath()
-				for _, path := range pathWithExtensions(resolvedPath) {
-					if target.provides(path) {
-						imp.knownTarget = target.label
-						continue handlingImports
-					}
-				}
-				d, err := a.findExistingDepProvidingImport(ctx, root, target, imp)
-				if err != nil {
-					return err
-				}
-				if d == "" {
-					// A target providing the import was not found on the
-					// existing dependencies or in a comment. Use other
-					// heuristics.
-					paths = append(paths, resolvedPath)
-					needingResolution[resolvedPath] = append(needingResolution[resolvedPath], imp)
-					continue
-				}
-				imp.knownTarget = d
-			}
-		}
-		if len(needingResolution) == 0 {
-			continue
-		}
-		res, err := a.loader.LoadImportPaths(ctx, target.rule, currentPkg, root, paths)
-		if err != nil {
-			return err
-		}
-		for path, imports := range needingResolution {
-			if target, ok := res[path]; ok {
-				for _, imp := range imports {
-					imp.knownTarget = redirectedLabel(target)
-				}
-			}
-		}
-	}
-	return nil
-}
-
-func pathWithExtensions(basename string) []string {
-	var paths []string
-	for _, ext := range extensions {
-		paths = append(paths, basename+ext)
-	}
-	return paths
-}
-
-var ambientModuleDeclRE = regexp.MustCompile("(?m)^\\s*declare\\s+module\\s+['\"]([^'\"]+)['\"]\\s+\\{")
-
-// findExistingDepProvidingImport looks through a map of the existing deps to
-// see if any of them provide the import in a way that can't be queried
-// for.  E.g. if the build rule has a "module_name" attribute or if one
-// of the .d.ts sources has an ambient module declaration.
-//
-// If the import already has a knownTarget, findRuleProvidingImport will
-// return the knownTarget.
-func (a *Analyzer) findExistingDepProvidingImport(ctx context.Context, root string, rt *resolvedTarget, i *ts_auto_depsImport) (string, error) {
-	if i.knownTarget != "" {
-		return i.knownTarget, nil
-	}
-
-	// check if any of the existing deps declare a module_name that matches the import
-	for _, r := range rt.dependencies {
-		resolvedImportPath := resolveAgainstModuleRoot(r, i.importPath)
-		if resolvedImportPath == i.importPath {
-			continue
-		}
-
-		// enumerate all the possible filepaths for the resolved import path, and
-		// compare against all the srcs
-		possibleImportPaths := possibleFilepaths(resolvedImportPath)
-		for _, src := range listAttribute(r, "srcs") {
-			for _, mi := range possibleImportPaths {
-				if mi == labelToPath(src) {
-					return r.GetName(), nil
-				}
-			}
-		}
-	}
-
-	// check if any of the other sources or the souces of any of the deps are .d.ts
-	// files which have ambient module declarations
-	var allRules []*appb.Rule
-	for _, r := range rt.dependencies {
-		allRules = append(allRules, r)
-	}
-	allRules = append(allRules, rt.rule)
-	for _, r := range allRules {
-		for _, src := range listAttribute(r, "srcs") {
-			fp := filepath.Join(root, labelToPath(src))
-			if !strings.HasSuffix(fp, ".d.ts") {
-				continue
-			}
-
-			contents, err := platform.ReadFile(ctx, fp)
-			if err != nil {
-				return "", fmt.Errorf("error reading file looking for ambient module decls: %s", err)
-			}
-
-			matches := ambientModuleDeclRE.FindAllStringSubmatch(string(contents), -1)
-
-			// put all the ambient modules into a set
-			declaredModules := make(map[string]bool)
-			for _, match := range matches {
-				declaredModules[match[1]] = true
-			}
-
-			// remove all the modules that were imported (ie all the modules that
-			// were being augmented/re-opened)
-			for _, mi := range parseImports(fp, contents) {
-				delete(declaredModules, mi.importPath)
-			}
-
-			if declaredModules[i.importPath] {
-				debugf("found import %s in ambient module declaration in %s", i.importPath, r.GetName())
-				return r.GetName(), nil
-			}
-		}
-	}
-	return "", nil
-}
-
-// stripTSExtension removes TypeScript extensions from a file path. If no
-// TypeScript extensions are present, the filepath is returned unaltered.
-func stripTSExtension(path string) string {
-	for _, ext := range extensions {
-		if strings.HasSuffix(path, ext) {
-			return strings.TrimSuffix(path, ext)
-		}
-	}
-	return path
-}
-
-// redirectedLabel looks in the target's tags for a tag starting with
-// 'alt_dep=' followed by a label. If such a tag is found, the label is
-// returned. Otherwise, the target's own label is returned.
-func redirectedLabel(target *appb.Rule) string {
-	for _, tag := range listAttribute(target, "tags") {
-		if trimmedTag := strings.TrimPrefix(tag, "alt_dep="); trimmedTag != tag {
-			return trimmedTag
-		}
-	}
-	// No 'alt_dep=' tag was present on the target so no redirects need to occur.
-	return target.GetName()
-}
-
-func labelToPath(label string) string {
-	_, pkg, file := edit.ParseLabel(label)
-	return platform.Normalize(filepath.Clean(filepath.Join(pkg, file)))
-}
-
-// generateReports generates reports for each label in labels.
-func (a *Analyzer) generateReports(labels []string, labelToTarget map[string]*resolvedTarget) ([]*arpb.DependencyReport, error) {
-	reports := make([]*arpb.DependencyReport, 0, len(labels))
-	for _, label := range labels {
-		target, ok := labelToTarget[label]
-		if !ok {
-			// This case should never happen.
-			platform.Fatalf("target %s no longer loaded", label)
-		}
-		report, err := a.generateReport(target)
-		if err != nil {
-			return nil, err
-		}
-		reports = append(reports, report)
-	}
-	return reports, nil
-}
-
-// generateReport generates a dependency report for a target.
-//
-// It adds imports for which no target could be found to unresolved imports.
-// Imports which had locatable targets are added to the necessary dependency
-// or missing dependency properties if the import was already present on target
-// or the import was not already present respectively.
-//
-// Missing source files detected during import resolution are added to the
-// reports. Dependencies which were present on the initial target but are not
-// required are added to the unnecessary dependency array.
-func (a *Analyzer) generateReport(target *resolvedTarget) (*arpb.DependencyReport, error) {
-	usedDeps := make(map[string]bool)
-	report := &arpb.DependencyReport{
-		Rule:              proto.String(target.label),
-		MissingSourceFile: target.missingSources,
-	}
-	for _, imports := range target.imports {
-	handlingImports:
-		for _, imp := range imports {
-			if imp.knownTarget == target.label {
-				continue
-			}
-			if imp.knownTarget == "" {
-				if strings.HasPrefix(imp.importPath, "goog:") {
-					// This feedback needs to be phrased this way since the
-					// updater.go relies on parsing the feedback strings to
-					// determine which 'goog:' imports to add.
-					report.Feedback = append(report.Feedback,
-						fmt.Sprintf(
-							"ERROR: %s:%d:%d: missing comment for 'goog:' import, "+
-								"please add a trailing comment to the import. E.g.\n  "+
-								"import Bar from '%s'; // from //foo:bar",
-							imp.location.sourcePath, imp.location.line, imp.location.offset, imp.importPath))
-				}
-				report.UnresolvedImport = append(report.UnresolvedImport, imp.resolvedPath())
-				continue
-			}
-
-			for _, dep := range target.deps() {
-				if edit.LabelsEqual(dep, imp.knownTarget, "") {
-					// fmt.Printf("%s provides %s\n", dep, imp.importPath)
-					usedDeps[dep] = true
-					report.NecessaryDependency = append(report.NecessaryDependency, imp.knownTarget)
-					continue handlingImports
-				}
-			}
-			report.MissingDependencyGroup = append(report.MissingDependencyGroup, &arpb.DependencyGroup{
-				Dependency: []string{edit.ShortenLabel(imp.knownTarget, "")},
-				ImportPath: []string{imp.importPath},
-			})
-		}
-	}
-
-	var unusedDeps []string
-	for _, dep := range target.deps() {
-		if _, ok := usedDeps[dep]; !ok {
-			unusedDeps = append(unusedDeps, dep)
-		}
-	}
-	labelToRule, err := a.loader.LoadRules("", unusedDeps)
-	if err != nil {
-		return nil, err
-	}
-	for label, rule := range labelToRule {
-		switch class := rule.GetRuleClass(); class {
-		case "ts_declaration":
-			// TypeScript declarations might declare arbitrary global symbols, so it
-			// is impossible to detect reliably if the import is being used (without
-			// compiling, at least).  Report that the rule has no explicit import as a
-			// warning, so that ts_auto_deps can decide to import remove or not based on a
-			// flag.
-			warning := fmt.Sprintf("WARNING: %s: keeping possibly used %s '%s'", rule.GetLocation(), class, label)
-			report.Feedback = append(report.Feedback, warning)
-		case "css_library":
-			// Similar to ts_declaration, ts_auto_deps can't reliably detect if css_library
-			// imports are being used, since ts_auto_deps can't currently parse @requirecss
-			// annotations.  Unlike ts_declaration, there's no flag to remove them, so
-			// there's no need to report a warning.
-		default:
-			// The contents of generated files aren't visible, so ts_auto_deps can't discover
-			// the import statements/deps that they contain.  To be safe, don't remove
-			// any unused deps, since they might be used by the generated file(s).
-			if len(target.generatedSourcePaths) == 0 {
-				report.UnnecessaryDependency = append(report.UnnecessaryDependency, label)
-			}
-		}
-	}
-	return report, nil
-}
-
-// relativePathLabel converts src to a label for a path relative to the
-// provided target. For example, a target '//foo/bar' and a src 'foo/bar/baz.ts'
-// would result in a relative path label of '//foo/bar:baz.ts'.
-func relativePathLabel(label, src string) string {
-	_, pkg, _ := edit.ParseLabel(label)
-	return fmt.Sprintf("//%s:%s", pkg, strings.TrimPrefix(src, pkg+"/"))
-}
-
-// listAttribute retrieves the attribute from target with name.
-func listAttribute(target *appb.Rule, name string) []string {
-	if a := attribute(target, name); a != nil {
-		return a.GetStringListValue()
-	}
-	return nil
-}
-
-func stringAttribute(target *appb.Rule, name string) string {
-	if a := attribute(target, name); a != nil {
-		return a.GetStringValue()
-	}
-	return ""
-}
-
-func attribute(target *appb.Rule, name string) *appb.Attribute {
-	for _, a := range target.GetAttribute() {
-		if a.GetName() == name {
-			return a
-		}
-	}
-	return nil
-}
-
-func isGenerated(rule *appb.Rule) bool {
-	return stringAttribute(rule, "generator_name") != ""
-}
diff --git a/ts_auto_deps/analyze/analyze_test.go b/ts_auto_deps/analyze/analyze_test.go
deleted file mode 100644
index 7a7d90a..0000000
--- a/ts_auto_deps/analyze/analyze_test.go
+++ /dev/null
@@ -1,657 +0,0 @@
-package analyze
-
-import (
-	"context"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"testing"
-
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-	"github.com/golang/protobuf/proto"
-	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/cmpopts"
-	"github.com/kylelemons/godebug/pretty"
-
-	appb "github.com/bazelbuild/buildtools/build_proto"
-	arpb "github.com/bazelbuild/rules_typescript/ts_auto_deps/proto"
-)
-
-var (
-	testTmpDir = os.Getenv("TEST_TMPDIR")
-)
-
-func TestMain(m *testing.M) {
-	if err := createWorkspaceFile(); err != nil {
-		platform.Fatalf("failed to create WORKSPACE file: %q", err)
-	}
-	os.Exit(m.Run())
-}
-
-const (
-	testDirectory = "a"
-)
-
-type fakeTargetLoader struct {
-	targetsByLabels      map[string]string
-	targetsByImportPaths map[string]string
-}
-
-func newFakeTargetLoader() *fakeTargetLoader {
-	return &fakeTargetLoader{
-		targetsByLabels:      make(map[string]string),
-		targetsByImportPaths: make(map[string]string),
-	}
-}
-
-func (bl *fakeTargetLoader) LoadRules(_ string, labels []string) (map[string]*appb.Rule, error) {
-	return bl.loadRules(bl.targetsByLabels, labels)
-}
-
-func (bl *fakeTargetLoader) LoadTargets(_ string, labels []string) (map[string]*appb.Target, error) {
-	targets := make(map[string]*appb.Target)
-	for _, l := range labels {
-		if strings.Contains(l, ".") {
-			targets[l] = &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()}
-		} else {
-			targets[l] = &appb.Target{Type: appb.Target_RULE.Enum()}
-		}
-	}
-	return targets, nil
-}
-
-func (bl *fakeTargetLoader) byLabel(label, value string) {
-	bl.targetsByLabels[label] = value
-}
-
-func (bl *fakeTargetLoader) LoadImportPaths(_ context.Context, _ *appb.Rule, _, _ string, paths []string) (map[string]*appb.Rule, error) {
-	return bl.loadRules(bl.targetsByImportPaths, paths)
-}
-
-func (bl *fakeTargetLoader) byImportPath(importPath, value string) {
-	bl.targetsByImportPaths[importPath] = value
-}
-
-func (bl *fakeTargetLoader) loadRules(source map[string]string, keys []string) (map[string]*appb.Rule, error) {
-	targets := make(map[string]*appb.Rule)
-	for _, key := range keys {
-		value, ok := source[key]
-		if !ok {
-			return nil, nil
-		}
-		var target appb.Rule
-		if err := proto.UnmarshalText(strings.Trim(value, " \n\r\t"), &target); err != nil {
-			return nil, err
-		}
-		targets[key] = &target
-	}
-	return targets, nil
-}
-
-type file struct {
-	path     string
-	contents []string
-}
-
-// testTarget represents a target with a label, a proto literal, and any import
-// paths that should resolve to the target.
-type testTarget struct {
-	label, protoLiteral string
-	importPaths         []string
-}
-
-func analyzeTargets(t *testing.T, labels []string, targets []*testTarget, files []*file) []*arpb.DependencyReport {
-	t.Helper()
-	for _, file := range files {
-		path := filepath.Join(testDirectory, file.path)
-		if err := createFile(path, file.contents...); err != nil {
-			t.Errorf("failed to create file %q: %q", file.path, err)
-			return nil
-		}
-		defer os.Remove(path)
-	}
-	for i, label := range labels {
-		labels[i] = fmt.Sprintf("//%s:%s", testDirectory, label)
-	}
-	loader := newFakeTargetLoader()
-	for _, t := range targets {
-		label := t.label
-		if !strings.HasPrefix(label, "//") {
-			label = fmt.Sprintf("//%s:%s", testDirectory, label)
-		}
-		r := fmt.Sprintf("name: %q\n%s", label, t.protoLiteral)
-		loader.byLabel(label, r)
-		for _, i := range t.importPaths {
-			loader.byImportPath(i, r)
-		}
-	}
-	r, err := New(loader).Analyze(context.Background(), testTmpDir, labels)
-	if err != nil {
-		t.Errorf("Analyze(%q): failed to generate reports: %q", labels, err)
-		return nil
-	}
-	if len(r) != len(labels) {
-		t.Errorf("Analyze(%q): got %d reports, wanted %d", labels, len(r), len(labels))
-		return nil
-	}
-	return r
-}
-
-func TestUnresolvedImports(t *testing.T) {
-	tests := []struct {
-		filepath, fileContents string
-		expectedImports        []string
-	}{
-		{"b/importer.ts", "import X from './path';", []string{"a/b/path"}},
-		{"b/importer.ts", "import X from 'absolute/path';", []string{"absolute/path"}},
-		{"b/importer.ts", "import X from '../../root';", []string{"root"}},
-		{"b/importer.ts", "import X from './multi/subpath';", []string{"a/b/multi/subpath"}},
-		{"b/importer.ts", "import X from '/rooted';", []string{"/rooted"}},
-		{"b/importer.ts", "import X from 'absolute/path';\nimport Y from './path';", []string{"absolute/path", "a/b/path"}},
-		{"b/importer.ts", "import X from 'some/path'; // from  //target:location", nil},
-		{"importer.d.ts", "import y from 'some/thing/missing';", []string{"some/thing/missing"}},
-	}
-	for _, test := range tests {
-		r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-			{"a_lib", fmt.Sprintf(`
-				rule_class: "ts_library"
-				attribute: <
-					name: "srcs"
-					string_list_value: "//a:%s"
-					type: 5
-				>`, test.filepath), nil},
-		}, []*file{{test.filepath, []string{test.fileContents}}})
-		if r == nil {
-			continue
-		}
-		if diff := pretty.Compare(r[0].GetUnresolvedImport(), test.expectedImports); diff != "" {
-			t.Errorf("Analyze(%q): failed to detect unresolved imports: (-got, +want)\n%s", test.fileContents, diff)
-		}
-	}
-}
-
-func TestUnnecessaryDependencies(t *testing.T) {
-	tests := [][]string{
-		[]string{"/* nothing */"},
-	}
-	for _, test := range tests {
-		r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-			{"a_lib", `
-				rule_class: "ts_library"
-				attribute: <
-					name: "srcs"
-					string_list_value: "//a:importer.ts"
-					type: 5
-				>
-				attribute: <
-					name: "deps"
-					string_list_value: "//a:b_lib"
-					type: 5
-				>`, nil},
-			{"b_lib", `
-				rule_class: "ts_library"`, nil},
-		}, []*file{{"t/importer.ts", test}})
-		if r == nil {
-			continue
-		}
-		if diff := pretty.Compare(r[0].GetUnnecessaryDependency(), []string{"//a:b_lib"}); diff != "" {
-			t.Errorf("Analyze(%q): failed to detect unnecessary dependencies: (-got, +want)\n%s", test, diff)
-		}
-	}
-}
-
-func TestNecessaryDependencies(t *testing.T) {
-	tests := [][]string{
-		[]string{"import x from 'b/target';"},
-		[]string{"// ts_auto_deps: x from //b:b_lib"},
-		[]string{"export x from 'b/target';"},
-	}
-	for _, test := range tests {
-		r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-			{"a_lib", `
-				rule_class: "ts_library"
-				attribute: <
-					type: 5
-					name: "srcs"
-					string_list_value: "//a:importer.ts"
-				>
-				attribute: <
-					type: 5
-					name: "deps"
-					string_list_value: "//b:b_lib"
-				>`, nil},
-			{"//b:b_lib", `
-				rule_class: "ts_library"
-				attribute: <
-					type: 5
-					name: "srcs"
-					string_list_value: "//b:target.ts"
-				>`, []string{"b/target"}},
-		}, []*file{{"importer.ts", test}})
-		if r == nil {
-			continue
-		}
-		if diff := pretty.Compare(r[0].GetNecessaryDependency(), []string{"//b:b_lib"}); diff != "" {
-			t.Errorf("Analyze(%q): failed to detect necessary deps: (-got, +want)\n%s", test, diff)
-		}
-	}
-}
-
-func TestMissingDependencies(t *testing.T) {
-	tests := []struct {
-		fileContents string
-		missingDeps  []string
-	}{
-		{"import x from 'b/c';\nimport y from 'angular';", []string{"//b/c:b_lib", "//third_party/javascript/typings/angular"}},
-		{"import * as angular from 'angular';\ndeclare module 'angular' { /* reopen */ }", []string{"//third_party/javascript/typings/angular"}},
-	}
-	for _, test := range tests {
-		r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-			{"a_lib", `
-				rule_class: "ts_library"
-				attribute: <
-					type: 5
-					name: "srcs"
-					string_list_value: "//a:x.ts"
-				>`, nil},
-			{"//b/c:b_lib", `
-				rule_class: "ts_library"
-				attribute: <
-					type: 5
-					name: "srcs"
-					string_list_value: "//b/c:index.ts"
-				>`, []string{"b/c"}},
-			{"//third_party/javascript/typings/angular:angular", `
-				rule_class: "ts_declaration"
-				attribute: <
-					type: 5
-					name: "srcs"
-					string_list_value: "//third_party/javascript/typings/angular:index.d.ts"
-				>`, []string{"angular"}},
-		}, []*file{{"x.ts", []string{test.fileContents}}})
-		if r == nil {
-			continue
-		}
-		if diff := pretty.Compare(missingDeps(r[0]), test.missingDeps); diff != "" {
-			t.Errorf("Analyze(%q): failed to detect missing dependencies: (-got, +want)\n%s", test.fileContents, diff)
-		}
-	}
-}
-
-func TestMissingSourceFile(t *testing.T) {
-	r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-		{"a_lib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "//a:f1.ts"
-				string_list_value: "//a:f2.ts"
-				string_list_value: "//a:p/f3.ts"
-			>`, nil},
-	}, []*file{{"f1.ts", []string{"/* nothing */"}}})
-	if r == nil {
-		t.FailNow()
-	}
-	if diff := pretty.Compare(r[0].GetMissingSourceFile(), []string{"//a:f2.ts", "//a:p/f3.ts"}); diff != "" {
-		t.Fatalf("Analyze: failed to detect missing source files: (-got, +want)\n%s", diff)
-	}
-}
-
-func TestMultipleLabels(t *testing.T) {
-	r := analyzeTargets(t, []string{"a_lib", "b_lib"}, []*testTarget{
-		{"a_lib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "//a:a/importer.ts"
-			>`, nil},
-		{"b_lib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "//a:b/importer.ts"
-			>`, nil},
-	}, []*file{
-		{"a/importer.ts", []string{"import X from './path';"}},
-		{"b/importer.ts", []string{"import X from './path';"}},
-	})
-	if r == nil {
-		t.FailNow()
-	}
-	tests := []struct {
-		label             string
-		unresolvedImports []string
-	}{
-		{"a_lib", []string{"a/a/path"}},
-		{"b_lib", []string{"a/b/path"}},
-	}
-	for i, test := range tests {
-		report := r[i]
-		if diff := pretty.Compare(report.GetUnresolvedImport(), test.unresolvedImports); diff != "" {
-			t.Errorf("Analyze(%q): failed to detect unresolved imports: (-got, +want)\n%s", test.label, diff)
-		}
-	}
-}
-
-func TestMultipleSourceFiles(t *testing.T) {
-	r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-		{"a_lib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "//a:importer.ts"
-				string_list_value: "//a:exporter.ts"
-			>`, nil},
-	}, []*file{
-		{"importer.ts", []string{"import {x} from 'a/exporter';"}},
-		{"exporter.ts", []string{"export let x = 12;"}},
-	})
-	if r == nil {
-		t.FailNow()
-	}
-	if diff := pretty.Compare(missingDeps(r[0]), []string{}); diff != "" {
-		t.Fatalf("Analyze: failed to detect missing dependencies: (-got, +want)\n%s", diff)
-	}
-}
-
-func TestRedirectTag(t *testing.T) {
-	r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-		{"a_lib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "//a:x.ts"
-			>`, nil},
-		{"dlib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "deps"
-				string_list_value: "//b:clib"
-			>`, nil},
-		{"clib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "//clib:c.ts"
-			>
-			attribute: <
-				type: 5
-				name: "tags"
-				string_list_value: "alt_dep=//d:dlib"
-			>`, []string{"b/c"}},
-	}, []*file{{"x.ts", []string{"import x from 'b/c';"}}})
-	if r == nil {
-		t.FailNow()
-	}
-	if diff := pretty.Compare(missingDeps(r[0]), []string{"//d:dlib"}); diff != "" {
-		t.Fatalf("Analyze: failed to detect missing dependencies: (-got, +want)\n%s", diff)
-	}
-}
-
-func TestCircularImport(t *testing.T) {
-	r := analyzeTargets(t, []string{"a_lib"}, []*testTarget{
-		{"a_lib", `
-			rule_class: "ts_library"
-			attribute: <
-				type: 5
-				name: "srcs"
-				string_list_value: "f1.ts"
-				string_list_value: "f2.ts"
-			>`, []string{"a/f1", "a/f2"}},
-	}, []*file{
-		{"f1.ts", []string{"import {x} from 'a/f1';", "export let y = x + 1;"}},
-		{"f2.ts", []string{"import {y} from 'a/f2';", "export let x = y + 0;"}},
-	})
-	if r == nil {
-		t.FailNow()
-	}
-	if diff := pretty.Compare(missingDeps(r[0]), []string{}); diff != "" {
-		t.Fatalf("Analyze: failed to detect missing dependencies: (-got, +want)\n%s", diff)
-	}
-}
-
-func TestListAttribute(t *testing.T) {
-	tests := []struct {
-		name  string
-		value []string
-	}{
-		{"srcs", []string{"a.ts", "b.ts"}},
-		{"deps", []string{":core"}},
-	}
-	result, err := createResult(`
-		target: <
-			type: 1
-			rule: <
-				name: "//tmp:tmp"
-				rule_class: "ts_library"
-				attribute: <
-					type: 5
-					name: "srcs"
-					string_list_value: "a.ts"
-					string_list_value: "b.ts"
-				>
-				attribute: <
-					type: 5
-					name: "deps"
-					string_list_value: ":core"
-				>
-			>
-		>`)
-	if err != nil {
-		t.Fatalf("failed to create result: %q", err)
-	}
-	for _, test := range tests {
-		attrValue := listAttribute(result.GetTarget()[0].GetRule(), test.name)
-		if attrValue == nil {
-			t.Errorf("listAttribute(%q): failed to find attribute", test.name)
-			continue
-		}
-		if diff := pretty.Compare(attrValue, test.value); diff != "" {
-			t.Errorf("listAttribute(%q): failed to get correct attribute values: (-got, +want)\n%s", test.name, diff)
-		}
-	}
-}
-
-func TestStringAttribute(t *testing.T) {
-	tests := []struct {
-		name, value string
-	}{
-		{"module_name", "@angular/core"},
-		{"module_root", ""},
-	}
-	result, err := createResult(`
-		target: <
-			type: 1
-			rule: <
-				name: "//tmp:tmp"
-				rule_class: "ts_library"
-				attribute: <
-					type: 5
-					name: "module_name"
-					string_value: "@angular/core"
-				>
-			>
-		>`)
-	if err != nil {
-		t.Fatalf("failed to create result: %q", err)
-	}
-	for _, test := range tests {
-		attrValue := stringAttribute(result.GetTarget()[0].GetRule(), test.name)
-		if diff := pretty.Compare(attrValue, test.value); diff != "" {
-			t.Errorf("stringAttribute(%q): failed to get correct attribute values: (-got, +want)\n%s", test.name, diff)
-		}
-	}
-}
-
-func TestSetSources(t *testing.T) {
-	tests := []struct {
-		name                   string
-		srcs                   []string
-		loadedSrcs             map[string]*appb.Target
-		err                    error
-		expected               map[string]*appb.Target
-		expectedLiteralPaths   []string
-		expectedGeneratedPaths []string
-	}{
-		{
-			"NoSources",
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-			nil,
-		},
-		{
-			"OneSource",
-			[]string{"//a:file.ts"},
-			map[string]*appb.Target{
-				"//a:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-			},
-			nil,
-			map[string]*appb.Target{
-				"//a:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-			},
-			[]string{"a/file.ts"},
-			nil,
-		},
-		{
-			"ExtraSources",
-			[]string{"//a:file.ts"},
-			map[string]*appb.Target{
-				"//a:file.ts":   &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:file.ts":   &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:generator": &appb.Target{Type: appb.Target_RULE.Enum()},
-				"//b:wiz":       &appb.Target{Type: appb.Target_RULE.Enum()},
-			},
-			nil,
-			map[string]*appb.Target{
-				"//a:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-			},
-			[]string{"a/file.ts"},
-			nil,
-		},
-		{
-			"MultipleLiteralSources",
-			[]string{"//a:file.ts", "//b:file.ts"},
-			map[string]*appb.Target{
-				"//a:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-			},
-			nil,
-			map[string]*appb.Target{
-				"//a:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:file.ts": &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-			},
-			[]string{"a/file.ts", "b/file.ts"},
-			nil,
-		},
-		{
-			"MultipleGeneratedSources",
-			[]string{"//b:generator", "//b:wiz"},
-			map[string]*appb.Target{
-				"//b:generator": &appb.Target{Type: appb.Target_RULE.Enum()},
-				"//b:wiz":       &appb.Target{Type: appb.Target_RULE.Enum()},
-			},
-			fmt.Errorf("rule has generated sources - cannot determine dependencies"),
-			nil,
-			nil,
-			nil,
-		},
-		{
-			"MixedSources",
-			[]string{"//a:file.ts", "//b:file.ts", "//b:generator", "//b:wiz"},
-			map[string]*appb.Target{
-				"//a:file.ts":   &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:file.ts":   &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:generator": &appb.Target{Type: appb.Target_RULE.Enum()},
-				"//b:wiz":       &appb.Target{Type: appb.Target_RULE.Enum()},
-			},
-			nil,
-			map[string]*appb.Target{
-				"//a:file.ts":   &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:file.ts":   &appb.Target{Type: appb.Target_SOURCE_FILE.Enum()},
-				"//b:generator": &appb.Target{Type: appb.Target_RULE.Enum()},
-				"//b:wiz":       &appb.Target{Type: appb.Target_RULE.Enum()},
-			},
-			[]string{"a/file.ts", "b/file.ts"},
-			[]string{"//b:generator", "//b:wiz"},
-		},
-		{
-			"MissingSources",
-			[]string{"//a:file.ts"},
-			nil,
-			fmt.Errorf("no source found for label %s", "//a:file.ts"),
-			nil,
-			nil,
-			nil,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			rt := &resolvedTarget{
-				rule: &appb.Rule{
-					Attribute: []*appb.Attribute{
-						&appb.Attribute{
-							Name:            proto.String("srcs"),
-							Type:            appb.Attribute_STRING_LIST.Enum(),
-							StringListValue: test.srcs,
-						},
-					},
-				},
-				sources: make(map[string]*appb.Target),
-			}
-
-			err := rt.setSources(test.loadedSrcs)
-			if !reflect.DeepEqual(err, test.err) {
-				t.Errorf("got err %q, expected %q", err, test.err)
-			}
-
-			if diff := cmp.Diff(rt.sources, test.expected, cmpopts.EquateEmpty(), cmp.Comparer(proto.Equal)); err == nil && diff != "" {
-				t.Errorf("failed to set correct sources: (-got, +want)\n%s", diff)
-			}
-		})
-	}
-}
-
-func missingDeps(report *arpb.DependencyReport) []string {
-	var deps []string
-	for _, group := range report.GetMissingDependencyGroup() {
-		deps = append(deps, group.GetDependency()...)
-	}
-	return deps
-}
-
-func createResult(str string) (*appb.QueryResult, error) {
-	var result appb.QueryResult
-	return &result, proto.UnmarshalText(strings.Trim(str, " \n\r\t"), &result)
-}
-
-func createFile(path string, content ...string) error {
-	if !filepath.IsAbs(path) {
-		path = filepath.Join(filepath.Dir(testTmpDir), path)
-	}
-	if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
-		return err
-	}
-	return ioutil.WriteFile(path, []byte(strings.Join(content, "\n")), 0666)
-}
-
-// This method creates a WORKSPACE file in the root of the Bazel test
-// directory. This allows the tests to resolve the root path of the
-// workspace by looking for the WORKSPACE file on disk.
-func createWorkspaceFile() error {
-	path := filepath.Join(filepath.Dir(testTmpDir), "WORKSPACE")
-	return ioutil.WriteFile(path, []byte("workspace(name = 'foo')"), 0666)
-}
diff --git a/ts_auto_deps/analyze/imports.go b/ts_auto_deps/analyze/imports.go
deleted file mode 100644
index 28f6501..0000000
--- a/ts_auto_deps/analyze/imports.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package analyze
-
-import (
-	"io/ioutil"
-	"path/filepath"
-	"regexp"
-	"strings"
-	"sync"
-
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace"
-)
-
-// ts_auto_depsImport represents a single import in a TypeScript source.
-type ts_auto_depsImport struct {
-	// importPath can be an ES6 path ('./foo/bar'), but also a namespace ('goog:...').
-	// This is the import path as it appears in the TypeScript source.
-	importPath string
-	// knownTarget is the (fully qualified) bazel target providing importPath.
-	// It's either found by locateMissingTargets or taken from a ts_auto_deps comment.
-	knownTarget string
-	location    sourceLocation
-}
-
-// resolvedPath is the path to the import relative to the root of the
-// workspace. For example, an import of './foo' in the 'bar/baz' directory
-// would have a path from root of 'bar/baz/foo'.
-//
-// Absolute imports have no resolvedPath since the physical location of
-// these imports depends on the dependencies of the target the source
-// location is a member of. For example, an import of 'foo/bar' would have
-// no resolvedPath.
-func (i *ts_auto_depsImport) resolvedPath() string {
-	if strings.HasPrefix(i.importPath, "./") || strings.HasPrefix(i.importPath, "../") {
-		// If the import is relative to the source location, use the source
-		// location to form a "canonical" path from the root.
-		return platform.Normalize(filepath.Clean(filepath.Join(filepath.Dir(i.location.sourcePath), i.importPath)))
-	} else if trim := strings.TrimPrefix(i.importPath, workspace.Name()+"/"); trim != i.importPath {
-		return trim
-	}
-	// The import is an absolute import and therefore does not have a definite
-	// resolved path.
-	return i.importPath
-}
-
-// sourceLocation points to a position in a source file.
-type sourceLocation struct {
-	// Workspace root relative source path.
-	sourcePath string
-	// offset and length are byte offsets, line is the 1-indexed source line (considering only \n as breaks).
-	offset, length, line int
-}
-
-// extractAllImports extracts the TypeScript imports from paths.
-//
-// paths should be relative to root. The root will be joined to each path
-// to construct a physical path to each file.
-func extractAllImports(root string, paths []string) (map[string][]*ts_auto_depsImport, []error) {
-	debugf("extracting imports from TypeScript files relative to %q: %q", root, paths)
-	allImports := make(map[string][]*ts_auto_depsImport)
-	var (
-		errors []error
-		mutex  sync.Mutex
-		group  sync.WaitGroup
-	)
-	for _, path := range paths {
-		group.Add(1)
-		go func(path string) {
-			defer group.Done()
-			imports, err := extractImports(root, path)
-			// Lock the mutex to prevent concurrent writes.
-			mutex.Lock()
-			defer mutex.Unlock()
-			if err != nil {
-				errors = append(errors, err)
-				return
-			}
-			allImports[path] = imports
-		}(path)
-	}
-	group.Wait()
-	return allImports, errors
-}
-
-// extractImports extracts the TypeScript imports from a single file. path
-// should be a path from the root to the file.
-func extractImports(root, path string) ([]*ts_auto_depsImport, error) {
-	d, err := ioutil.ReadFile(filepath.Join(root, path))
-	if err != nil {
-		return nil, err
-	}
-	return parseImports(path, d), nil
-}
-
-const (
-	ts_auto_depsFrom  = `^[ \t]*//[ \t]+ts_auto_deps:[^\n]*?from[ \t]+(?P<Target>//\S+)$`
-	importPreface     = `^[ \t]*(?:import|export)\b\s*`
-	wildcardTerm      = `\*(?:\s*as\s+\S+)?` // "as..." is optional to match exports.
-	identifiersClause = `(?:\{[^}]*\}|\S+|` + wildcardTerm + `)`
-	symbolsTerm       = `(?:` + identifiersClause + `(?:,\s*` + identifiersClause + `)?\s*\bfrom\b\s*)?`
-	url               = `['"](?P<URL>[^'";]+)['"]\s*;?`
-	namespaceComment  = `(?:\s*//[ \t]*from[ \t]+(?P<Target>//\S+)$)?`
-)
-
-var importRE = regexp.MustCompile("(?ms)" +
-	"(?:" + ts_auto_depsFrom + ")|" +
-	"(?:" + importPreface + symbolsTerm + url + namespaceComment + ")")
-
-// parseImports scans contents for imports (ES6 modules, ts_auto_deps comments), and
-// returns a list of ts_auto_depsImports. knownTarget is already filled in for imports
-// that have ts_auto_deps comments.
-func parseImports(sourcePath string, contents []byte) []*ts_auto_depsImport {
-	var imports []*ts_auto_depsImport
-	lastOffset := 0
-	line := 1
-	column := 1
-	for _, matchIndices := range importRE.FindAllSubmatchIndex(contents, -1) {
-		imp := &ts_auto_depsImport{}
-		imports = append(imports, imp)
-		// matchIndices[0, 1]: full RE match
-		imp.location.sourcePath = sourcePath
-		for lastOffset < matchIndices[1] {
-			// Iterate to the *end* of the import statement.
-			// The ts_auto_deps comment must be placed at the end of the "import" statement.
-			// This offset has to be exactly the end of the import for ts_auto_deps later on
-			// to insert the '// from' comment in the correct line.
-			column++
-			if contents[lastOffset] == '\n' {
-				line++
-				column = 1
-			}
-			lastOffset++
-		}
-		imp.location.offset = matchIndices[0]
-		imp.location.length = matchIndices[1] - matchIndices[0]
-		imp.location.line = line
-		if matchIndices[2] >= 0 {
-			// matchIndices[2, 3]: Target for a // ts_auto_deps: ... from ... comment.
-			imp.knownTarget = string(contents[matchIndices[2]:matchIndices[3]])
-		} else {
-			// matchIndices[4, 5]: URL in import x from 'url';
-			imp.importPath = string(contents[matchIndices[4]:matchIndices[5]])
-		}
-		if matchIndices[6] >= 0 {
-			// matchIndices[6, 7]: Target for a // from comment
-			imp.knownTarget = string(contents[matchIndices[6]:matchIndices[7]])
-		}
-	}
-	return imports
-}
diff --git a/ts_auto_deps/analyze/imports_test.go b/ts_auto_deps/analyze/imports_test.go
deleted file mode 100644
index 029df0e..0000000
--- a/ts_auto_deps/analyze/imports_test.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package analyze
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/kylelemons/godebug/pretty"
-)
-
-func TestParseImports(t *testing.T) {
-	tests := []struct{ text, importPath, knownTarget string }{
-		// Imports
-		{"import {a} from 'named';", "named", ""},
-		{"code before;\n import {a} from 'before after'; code after",
-			"before after", ""},
-		{"import A from 'default';", "default", ""},
-		{"import A$X from 'default';", "default", ""},
-		{"import {x as $} from 'default';", "default", ""},
-		{"import ü from 'default';", "default", ""},
-		{"import * as prefix from 'wildcard prefixed';", "wildcard prefixed", ""},
-		{" \t import {A, B as C} from 'renamed';", "renamed", ""},
-		{"import 'sideeffect import';", "sideeffect import", ""},
-		{"import\n {A\n, B} from 'newlines';", "newlines", ""},
-		{"import*as prefix from'no whitespace';", "no whitespace", ""},
-		{"import Symbol from 'goog:some.Symbol';  // from //target:location",
-			"goog:some.Symbol", "//target:location"},
-		{"import Symbol from 'goog:some.Symbol';//from  //target:location",
-			"goog:some.Symbol", "//target:location"},
-		{"import {a} from 'missing semi'", "missing semi", ""},
-		{"import {a} from 'missing semi' // from //target:location",
-			"missing semi", "//target:location"},
-		{"import A, {B, C} from 'mixed';", "mixed", ""},
-		{"import A, * as B from 'mixed';", "mixed", ""},
-		{"import * as B, A from 'inverted mixed';", "inverted mixed", ""},
-		// Exports
-		{"export * from 'wildcard';", "wildcard", ""},
-		{"export {a, b} from 'named';", "named", ""},
-		{"export {} from 'empty import';", "empty import", ""},
-		{"export {a as b} from 'renamed';", "renamed", ""},
-		{"export\n {A\n, B} from 'newlines';", "newlines", ""},
-		{"export*from'no whitespace';", "no whitespace", ""},
-		{"export{}from'no whitespace';", "no whitespace", ""},
-		// Comments
-		{"x;\n// ts_auto_deps: ng from //some/global:rule\ny;", "", "//some/global:rule"},
-		{"// ts_auto_deps: ng from //foo/bar from //some/global:rule", "", "//some/global:rule"},
-	}
-
-	for i, tst := range tests {
-		imports := parseImports(fmt.Sprintf("test%d.ts", i), []byte(tst.text))
-		if len(imports) != 1 {
-			t.Errorf("parseImports(%q): got %d import(s), want 1", tst.text, len(imports))
-			continue
-		}
-		imp := imports[0]
-		if imp.importPath != tst.importPath {
-			t.Errorf("parseImports(%q): got %q, want %q", tst.text, imp.importPath, tst.importPath)
-		}
-		if imp.knownTarget != tst.knownTarget {
-			t.Errorf("parseImports(%q): got %q, want %q", tst.text, imp.knownTarget, tst.knownTarget)
-		}
-	}
-}
-
-func TestParseImportsSourceLocation(t *testing.T) {
-	tests := []struct {
-		text                   string
-		expectedSourceLocation sourceLocation
-	}{
-		{"import {a} from 'named';", sourceLocation{line: 1, offset: 0, length: 24}},
-		{"\n\timport {a} from 'named';", sourceLocation{line: 2, offset: 1, length: 25}},
-	}
-	for i, tst := range tests {
-		sourcePath := fmt.Sprintf("test%d.ts", i)
-		imports := parseImports(sourcePath, []byte(tst.text))
-		if len(imports) != 1 {
-			t.Errorf("parseImports(%q): got %d import(s), want 1", tst.text, len(imports))
-			continue
-		}
-		imp := imports[0]
-		tst.expectedSourceLocation.sourcePath = sourcePath
-		if diff := pretty.Compare(imp.location, tst.expectedSourceLocation); diff != "" {
-			t.Errorf("parseImports(%q): expected different source location: (-got, +want)\n%s", tst.text, diff)
-		}
-	}
-}
diff --git a/ts_auto_deps/analyze/loader.go b/ts_auto_deps/analyze/loader.go
deleted file mode 100644
index 4a98600..0000000
--- a/ts_auto_deps/analyze/loader.go
+++ /dev/null
@@ -1,737 +0,0 @@
-package analyze
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"time"
-
-	"github.com/bazelbuild/buildtools/edit"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace"
-	"github.com/golang/protobuf/proto"
-
-	appb "github.com/bazelbuild/buildtools/build_proto"
-)
-
-// pkgCacheEntry represents a set of loaded rules and a mapping from alias
-// to rules from a package.
-type pkgCacheEntry struct {
-	// rules is all rules in a package.
-	rules []*appb.Rule
-	// aliases is a map from an alias label to the actual rule of the alias.
-	aliases map[string]*appb.Rule
-}
-
-// QueryBasedTargetLoader uses Bazel query to load targets from BUILD files.
-type QueryBasedTargetLoader struct {
-	workdir     string
-	bazelBinary string
-
-	// pkgCache is a mapping from a package to all of the rules in said
-	// package along with a map from aliases to actual rules.
-	//
-	// Keys are of the form of "<visibility>|<package>" where visibility
-	// is the package that rules in package must be visible to and package
-	// is the actual package that has been loaded and cached.
-	//
-	// Since a new target loader is constructed for each directory being
-	// analyzed in the "-recursive" case, these caches will be garbage
-	// collected between directories.
-	pkgCache map[string]*pkgCacheEntry
-	// labelCache is a mapping from a label to its loaded target.
-	labelCache map[string]*appb.Target
-
-	// queryCount is the total number of queries executed by the target loader.
-	queryCount int
-}
-
-// NewQueryBasedTargetLoader constructs a new QueryBasedTargetLoader rooted
-// in workdir.
-func NewQueryBasedTargetLoader(workdir, bazelBinary string) *QueryBasedTargetLoader {
-	return &QueryBasedTargetLoader{
-		workdir:     workdir,
-		bazelBinary: bazelBinary,
-
-		pkgCache:   make(map[string]*pkgCacheEntry),
-		labelCache: make(map[string]*appb.Target),
-	}
-}
-
-// LoadRules uses Bazel query to load rules associated with labels from BUILD
-// files.
-func (q *QueryBasedTargetLoader) LoadRules(pkg string, labels []string) (map[string]*appb.Rule, error) {
-	labelToTarget, err := q.LoadTargets(pkg, labels)
-	if err != nil {
-		return nil, err
-	}
-
-	labelToRule := make(map[string]*appb.Rule)
-	for _, label := range labels {
-		target := labelToTarget[label]
-		if target.GetType() == appb.Target_RULE {
-			labelToRule[label] = target.GetRule()
-		} else {
-			return nil, fmt.Errorf("target %s contains object of type %q instead of type %q", label, target.GetType(), appb.Target_RULE)
-		}
-	}
-	return labelToRule, nil
-}
-
-// LoadTargets uses Bazel query to load targets associated with labels from BUILD
-// files.
-func (q *QueryBasedTargetLoader) LoadTargets(pkg string, labels []string) (map[string]*appb.Target, error) {
-	var labelCacheMisses []string
-	for _, label := range labels {
-		if _, ok := q.labelCache[labelCacheKey(pkg, label)]; !ok {
-			labelCacheMisses = append(labelCacheMisses, label)
-		}
-	}
-	if len(labelCacheMisses) > 0 {
-		var queries []string
-		if pkg == "" {
-			queries = labelCacheMisses
-		} else {
-			for _, label := range labelCacheMisses {
-				queries = append(queries, fmt.Sprintf("visible(%s:*, %s)", pkg, label))
-			}
-		}
-		r, err := q.batchQuery(queries)
-		if err != nil {
-			return nil, err
-		}
-		for _, target := range r.GetTarget() {
-			label, err := q.targetLabel(target)
-			if err != nil {
-				return nil, err
-			}
-			q.labelCache[labelCacheKey(pkg, label)] = target
-		}
-		for _, label := range labelCacheMisses {
-			key := labelCacheKey(pkg, label)
-			if _, ok := q.labelCache[key]; !ok {
-				// Set to nil so the result exists in the cache and is not
-				// loaded again. If the nil is not added at the appropriate
-				// cache key, LoadLabels will attempt to load it again when
-				// next requested instead of getting a cache hit.
-				q.labelCache[key] = nil
-			}
-		}
-	}
-	labelToTarget := make(map[string]*appb.Target)
-	for _, label := range labels {
-		labelToTarget[label] = q.labelCache[labelCacheKey(pkg, label)]
-	}
-	return labelToTarget, nil
-}
-
-func labelCacheKey(currentPkg, label string) string {
-	return currentPkg + "^" + label
-}
-
-// possibleFilepaths generates the possible filepaths for the ts import path.
-// e.g. google3/foo/bar could be foo/bar.ts or foo/bar.d.ts or foo/bar/index.ts, etc.
-// Also handles special angular import paths (.ngfactory and .ngsummary).
-func possibleFilepaths(importPath string) []string {
-	// If the path has a suffix of ".ngfactory" or ".ngsummary", it might
-	// be an Angular AOT generated file. We can infer the target as we
-	// infer its corresponding ngmodule target by simply stripping the
-	// ".ngfactory" / ".ngsummary" suffix
-	importPath = strings.TrimSuffix(strings.TrimSuffix(importPath, ".ngsummary"), ".ngfactory")
-	importPath = strings.TrimPrefix(importPath, workspace.Name()+"/")
-
-	var possiblePaths []string
-
-	possiblePaths = append(possiblePaths, pathWithExtensions(importPath)...)
-	possiblePaths = append(possiblePaths, pathWithExtensions(filepath.Join(importPath, "index"))...)
-
-	return possiblePaths
-}
-
-// LoadImportPaths uses Bazel Query to load targets associated with import
-// paths from BUILD files.
-func (q *QueryBasedTargetLoader) LoadImportPaths(ctx context.Context, targetToAnalyze *appb.Rule, currentPkg, workspaceRoot string, paths []string) (map[string]*appb.Rule, error) {
-	debugf("loading imports visible to %q relative to %q: %q", currentPkg, workspaceRoot, paths)
-	results := make(map[string]*appb.Rule)
-
-	addedPaths := make(map[string]bool)
-	var possibleFilePaths []string
-	possiblePathToPaths := make(map[string][]string)
-	// for all the normalized typescript import paths, generate all the possible
-	// corresponding file paths
-	for _, path := range paths {
-		if strings.HasPrefix(path, "goog:") {
-			// 'goog:' imports are resolved using an sstable.
-			results[path] = nil
-			continue
-		}
-		if strings.HasPrefix(path, "@") {
-			continue
-		}
-
-		if _, ok := addedPaths[path]; !ok {
-			addedPaths[path] = true
-
-			// there isn't a one to one mapping from ts import paths to file
-			// paths, so look for all the possible file paths
-			pfs := possibleFilepaths(path)
-			possibleFilePaths = append(possibleFilePaths, pfs...)
-			// map the file paths back to the import paths so we can map the file
-			// labels back to the import paths
-			for _, pf := range pfs {
-				possiblePathToPaths[pf] = append(possiblePathToPaths[pf], path)
-			}
-		}
-	}
-
-	// query for all the possible filepaths, to determine which ones are real
-	r, err := q.batchQuery(possibleFilePaths)
-	if err != nil {
-		return nil, err
-	}
-	var fileLabels, packages []string
-	fileToGeneratorLabel := make(map[string]string)
-	pathToLabels := make(map[string][]string)
-	// get the labels for all the files which exist
-	for _, target := range r.GetTarget() {
-		label, err := q.fileLabel(target)
-		if err != nil {
-			return nil, err
-		}
-		switch target.GetType() {
-		case appb.Target_GENERATED_FILE:
-			file := target.GetGeneratedFile()
-			generator := file.GetGeneratingRule()
-			label = file.GetName()
-
-			fileLabels = append(fileLabels, label)
-			_, pkg, _ := edit.ParseLabel(label)
-			packages = append(packages, pkg)
-			// a generated file can be included as a source by referencing the label
-			// of the generated file, or the label of the generating rule, so check
-			// for both
-			fileToGeneratorLabel[labelToPath(label)] = labelToPath(generator)
-			// map file label back to the import paths so that they can be looked for
-			// in the srcs of the rules
-			for _, path := range possiblePathToPaths[labelToPath(label)] {
-				pathToLabels[path] = append(pathToLabels[path], label)
-			}
-		case appb.Target_SOURCE_FILE:
-			fileLabels = append(fileLabels, label)
-			_, pkg, _ := edit.ParseLabel(label)
-			packages = append(packages, pkg)
-			// map file label back to the import paths so that they can be looked for
-			// in the srcs of the rules
-			for _, path := range possiblePathToPaths[labelToPath(label)] {
-				pathToLabels[path] = append(pathToLabels[path], label)
-			}
-		}
-	}
-
-	// load all the rules in all the packages files were found in, so we can look
-	// for aliases and reexporting libraries in the same package
-	pkgToAllRules, pkgToActualToAlias, err := q.loadAllRulesInPackages("", packages)
-	if err != nil {
-		return nil, err
-	}
-
-	for _, path := range paths {
-		// look up the corresponding file label(s) for the normalized typescript
-		// import path
-		for _, label := range pathToLabels[path] {
-			_, pkg, _ := edit.ParseLabel(label)
-			// get the file path that corresponds to the normalized typescript import
-			// path
-			filePath := labelToPath(label)
-			allRules := pkgToAllRules[pkg]
-			actualToAlias := pkgToActualToAlias[pkg]
-			var matchingDeps []*appb.Rule
-			for _, candidate := range typeScriptRules(allRules) {
-				// check if the rule has the file or the generator of the file in its
-				// srcs
-				possibleSources := []string{filePath}
-				if gl, ok := fileToGeneratorLabel[filePath]; ok {
-					possibleSources = append(possibleSources, gl)
-				}
-				provides, err := q.ruleProvidesImports(candidate, srcsContainsAnyFilePath(possibleSources))
-				if err != nil {
-					return nil, err
-				}
-				if !provides {
-					continue
-				}
-
-				if alias, ok := actualToAlias[candidate.GetName()]; ok {
-					candidate = alias
-				}
-				matchingDeps = append(matchingDeps, candidate)
-			}
-			if len(matchingDeps) > 0 {
-				canonicalRule, err := q.chooseCanonicalDep(currentPkg, targetToAnalyze, matchingDeps)
-				if err != nil {
-					return nil, err
-				}
-				results[path] = canonicalRule
-			}
-		}
-	}
-
-	return results, nil
-}
-
-// chooseCanonicalDep chooses between rules which include the imported file as
-// a source (ie the rule that includes the file as a src, and any reexporting
-// libraries).
-//
-// It filters the rules in a 3 stage process:
-//
-// 1. If only one of the rules is visible, choose that one, since the rule
-// creator intended it to be imported.
-//
-// 2. If all or none of the rules are visible, choose the rule that directly
-// includes the file as a src, since that reduces the chance of introducing
-// circular dependencies.
-//
-// 3. Choose the rule that is already included as a dep.
-func (q *QueryBasedTargetLoader) chooseCanonicalDep(currentPkg string, targetToAnalyze *appb.Rule, deps []*appb.Rule) (*appb.Rule, error) {
-	// check for visibility
-	filterForVisibility := func(deps []*appb.Rule) ([]*appb.Rule, error) {
-		var labels []string
-		for _, d := range deps {
-			labels = append(labels, d.GetName())
-		}
-		visibleDepsMap, err := q.LoadRules(currentPkg, labels)
-		if err != nil {
-			return nil, err
-		}
-
-		var visibleDeps []*appb.Rule
-		for _, d := range visibleDepsMap {
-			if d != nil {
-				visibleDeps = append(visibleDeps, d)
-			}
-		}
-
-		return visibleDeps, nil
-	}
-
-	// if there's a visible reexporting lib and a visible lib with the src, favor
-	// the lib with the src, to reduce the chance of introducing a circular
-	// dependency
-	filterForBaseLibs := func(deps []*appb.Rule) ([]*appb.Rule, error) {
-		var baseDeps []*appb.Rule
-		for _, d := range deps {
-			if !isReexportingLib(d) {
-				baseDeps = append(baseDeps, d)
-			}
-		}
-
-		return baseDeps, nil
-	}
-
-	// favor the dep that's already on the rule
-	filterForExistingDeps := func(deps []*appb.Rule) ([]*appb.Rule, error) {
-		var existingDeps []*appb.Rule
-		for _, d := range deps {
-			for _, existing := range listAttribute(targetToAnalyze, "deps") {
-				if d.GetName() == existing {
-					existingDeps = append(existingDeps, d)
-				}
-			}
-		}
-
-		return existingDeps, nil
-	}
-
-	filters := []func(deps []*appb.Rule) ([]*appb.Rule, error){
-		filterForVisibility,
-		filterForBaseLibs,
-		filterForExistingDeps,
-	}
-
-	// for each filter, return if it returned a single rule, narrow the set of deps if
-	// it discarded some, but not all, and try the full set with the next filter if it
-	// discarded them all
-	for _, filter := range filters {
-		filteredDeps, err := filter(deps)
-		if err != nil {
-			return nil, err
-		}
-		if len(filteredDeps) == 1 {
-			return filteredDeps[0], nil
-		} else if len(filteredDeps) > 0 {
-			deps = filteredDeps
-		}
-	}
-
-	// no filter got down to a single rule, just return the first
-	return deps[0], nil
-}
-
-// ruleLabel returns the label for a target which is a rule.  Returns an error if
-// target is not a rule.
-func (q *QueryBasedTargetLoader) ruleLabel(target *appb.Target) (string, error) {
-	if t := target.GetType(); t != appb.Target_RULE {
-		return "", fmt.Errorf("target contains object of type %q instead of type %q", t, appb.Target_RULE)
-	}
-	return target.GetRule().GetName(), nil
-}
-
-// fileLabel returns the label for a target which is a file.  Returns an error if
-// target is not a source file or a generated file.
-func (q *QueryBasedTargetLoader) fileLabel(target *appb.Target) (string, error) {
-	switch t := target.GetType(); t {
-	case appb.Target_GENERATED_FILE:
-		return target.GetGeneratedFile().GetName(), nil
-	case appb.Target_SOURCE_FILE:
-		return target.GetSourceFile().GetName(), nil
-	default:
-		return "", fmt.Errorf("target contains object of type %q instead of type %q or %q", t, appb.Target_SOURCE_FILE, appb.Target_GENERATED_FILE)
-	}
-}
-
-// targetLabel returns the label for a target.  Returns an error if target is an
-// unknown type.
-func (q *QueryBasedTargetLoader) targetLabel(target *appb.Target) (string, error) {
-	switch t := target.GetType(); t {
-	case appb.Target_GENERATED_FILE:
-		return target.GetGeneratedFile().GetName(), nil
-	case appb.Target_SOURCE_FILE:
-		return target.GetSourceFile().GetName(), nil
-	case appb.Target_RULE:
-		return target.GetRule().GetName(), nil
-	case appb.Target_PACKAGE_GROUP:
-		return target.GetPackageGroup().GetName(), nil
-	case appb.Target_ENVIRONMENT_GROUP:
-		return target.GetEnvironmentGroup().GetName(), nil
-	default:
-		return "", fmt.Errorf("target contains object of unknown type %q", t)
-	}
-}
-
-// batchQuery runs a set of queries with a single call to Bazel query and the
-// '--keep_going' flag.
-func (q *QueryBasedTargetLoader) batchQuery(queries []string) (*appb.QueryResult, error) {
-	// Join all of the queries with a '+' character according to Bazel's
-	// syntax for running multiple queries.
-	return q.query("--keep_going", strings.Join(queries, "+"))
-}
-
-func (q *QueryBasedTargetLoader) query(args ...string) (*appb.QueryResult, error) {
-	n := len(args)
-	if n < 1 {
-		return nil, fmt.Errorf("expected at least one argument")
-	}
-	query := args[n-1]
-	if query == "" {
-		// An empty query was provided so return an empty result without
-		// making a call to Bazel.
-		return &appb.QueryResult{}, nil
-	}
-	var stdout, stderr bytes.Buffer
-	args = append([]string{"query", "--output=proto"}, args...)
-	q.queryCount++
-	debugf("executing query #%d in %q: %s %s %q", q.queryCount, q.workdir, q.bazelBinary, strings.Join(args[:len(args)-1], " "), query)
-	cmd := exec.Command(q.bazelBinary, args...)
-	cmd.Dir = q.workdir
-	cmd.Stdout = &stdout
-	cmd.Stderr = &stderr
-	startTime := time.Now()
-	if err := cmd.Run(); err != nil {
-		// Exit status 3 is a direct result of one or more queries in a set of
-		// queries not returning a result while running with the '--keep_going'
-		// flag. Since one query failing to return a result does not hinder the
-		// other queries from returning a result, ignore these errors.
-		//
-		// Herb prints "printing partial results" to indicate the same as bazel's
-		// exit status 3
-		if err.Error() != "exit status 3" && !strings.Contains(stderr.String(), "printing partial results") {
-			// The error provided as a result is less useful than the contents of
-			// stderr for debugging.
-			return nil, fmt.Errorf(stderr.String())
-		}
-	}
-	debugf("query #%d took %v", q.queryCount, time.Since(startTime))
-	var result appb.QueryResult
-	if err := proto.Unmarshal(stdout.Bytes(), &result); err != nil {
-		return nil, err
-	}
-	return &result, nil
-}
-
-// ruleProvidesImports checks if the rule directly provides the import, or if
-// it's a reexporting lib, if one of its deps does.
-func (q *QueryBasedTargetLoader) ruleProvidesImports(rule *appb.Rule, srcMatcher func(rule *appb.Rule) bool) (bool, error) {
-	if srcMatcher(rule) {
-		return true, nil
-	}
-
-	if !isReexportingLib(rule) {
-		return false, nil
-	}
-
-	// if the rule is a reexporting library, load all the rules that the rule
-	// reexports, and check if they provide the imported paths.  This only handles
-	// one level of reexport.
-	_, pkg, _ := edit.ParseLabel(rule.GetName())
-	// TODO(alexeagle): Batch calls to LoadLabels. Batching calls to ruleProvidesImport
-	// would also be required.
-	exportedRules, err := q.LoadRules(pkg, exportedLabels(rule))
-	if err != nil {
-		return false, err
-	}
-	for _, exportedRule := range exportedRules {
-		if srcMatcher(exportedRule) {
-			return true, nil
-		}
-	}
-
-	return false, nil
-}
-
-// exportedLabels returns the labels exported by rule. Exported labels are the
-// deps of a rule if the rule is an alias.
-func exportedLabels(rule *appb.Rule) []string {
-	var exported []string
-	if isReexportingLib(rule) {
-		exported = append(exported, listAttribute(rule, "deps")...)
-	}
-	return exported
-}
-
-// isReexportingLib checks if a library has no sources, which the TS rules use a
-// way to mark a library as an alias.
-func isReexportingLib(rule *appb.Rule) bool {
-	return len(listAttribute(rule, "srcs")) == 0
-}
-
-// srcsContainsPath returns a function, which takes a rule, which returns true
-// if the rule has a src which matches one of the possible filepaths for the
-// provided typescript import path.
-func srcsContainsPath(path string) func(rule *appb.Rule) bool {
-	return func(rule *appb.Rule) bool {
-		resolvedImportPath := resolveAgainstModuleRoot(rule, path)
-
-		// enumerate all the possible filepaths for the resolved import path, and
-		// compare against all the srcs
-		possibleImportPaths := possibleFilepaths(resolvedImportPath)
-		for _, src := range listAttribute(rule, "srcs") {
-			for _, mi := range possibleImportPaths {
-				if mi == labelToPath(src) {
-					return true
-				}
-			}
-		}
-
-		return false
-	}
-}
-
-// srcsContainsFilePath returns a function which takes a rule, which returns
-// true if the rule has a src which, if pathified, equals one of the filePaths.
-func srcsContainsAnyFilePath(filePaths []string) func(rule *appb.Rule) bool {
-	return func(rule *appb.Rule) bool {
-		for _, filePath := range filePaths {
-			for _, src := range listAttribute(rule, "srcs") {
-				if filePath == labelToPath(src) {
-					return true
-				}
-			}
-		}
-
-		return false
-	}
-}
-
-// loadAllRulesInPackages loads all rules in all packages.
-//
-// If an alias or aliases are present in the package, the rules for each alias'
-// 'actual' attribute are loaded and a map from each 'actual' rule to its alias
-// rule is constructed.
-//
-// loadAllRulesInPackages returns two maps. The first map is a map from a package
-// label to all of the rules in the package. The second map is a map from a
-// package to the map of 'actual' rules to alias rules for that package.
-func (q *QueryBasedTargetLoader) loadAllRulesInPackages(currentPkg string, packages []string) (map[string][]*appb.Rule, map[string]map[string]*appb.Rule, error) {
-	var missingPackages []string
-	for _, pkg := range packages {
-		if _, ok := q.pkgCache[pkgCacheKey(currentPkg, pkg)]; !ok {
-			missingPackages = append(missingPackages, pkg)
-		}
-	}
-	if len(missingPackages) > 0 {
-		// Load any packages not already available in the cache.
-		var queries []string
-		pkgToRules := make(map[string][]*appb.Rule)
-		pkgToAliasToRule := make(map[string]map[string]*appb.Rule)
-		for _, pkg := range missingPackages {
-			if currentPkg != "" {
-				queries = append(queries, fmt.Sprintf("visible(%s:*, %s:*)", currentPkg, pkg))
-			} else {
-				queries = append(queries, fmt.Sprintf("%s:*", pkg))
-			}
-			pkgToAliasToRule[pkg] = make(map[string]*appb.Rule)
-		}
-		r, err := q.batchQuery(queries)
-		if err != nil {
-			return nil, nil, err
-		}
-		actualToAlias := make(map[string]*appb.Rule)
-		pkgToActuals := make(map[string][]string)
-		for _, target := range r.GetTarget() {
-			if target.GetType() == appb.Target_RULE {
-				rule := target.GetRule()
-				_, pkg, _ := edit.ParseLabel(rule.GetName())
-				if rule.GetRuleClass() == "alias" {
-					// if the package contains an alias, derefence it (but only one layer
-					// of aliases)
-					actual := stringAttribute(rule, "actual")
-					if actual == "" {
-						// probably an alias with a select statement as the value for
-						// 'actual' - just ignore
-						platform.Infof(`alias %q has non-string "actual" attribute`, rule.GetName())
-						continue
-					}
-					actualToAlias[actual] = rule
-					pkgToActuals[pkg] = append(pkgToActuals[pkg], actual)
-				} else {
-					pkgToRules[pkg] = append(pkgToRules[pkg], rule)
-				}
-			}
-		}
-		for pkg, actuals := range pkgToActuals {
-			// Load all the aliased targets, checking if they're visible from the
-			// package where they're aliased from
-			resolvedActuals, err := q.LoadTargets(pkg, actuals)
-			if err != nil {
-				return nil, nil, err
-			}
-			for actual, target := range resolvedActuals {
-				// aliases can be for anything, but deps can only be rules, so ignore
-				// other aliased targets
-				if target.GetType() != appb.Target_RULE {
-					continue
-				}
-
-				rule := target.GetRule()
-				alias := actualToAlias[actual]
-				_, pkg, _ := edit.ParseLabel(alias.GetName())
-				pkgToAliasToRule[pkg][rule.GetName()] = alias
-				pkgToRules[pkg] = append(pkgToRules[pkg], rule)
-			}
-		}
-		for _, pkg := range missingPackages {
-			q.pkgCache[pkgCacheKey(currentPkg, pkg)] = &pkgCacheEntry{
-				rules:   pkgToRules[pkg],
-				aliases: pkgToAliasToRule[pkg],
-			}
-		}
-	}
-
-	pkgToRules := make(map[string][]*appb.Rule)
-	pkgToRuleToAlias := make(map[string]map[string]*appb.Rule)
-	for _, pkg := range packages {
-		cacheEntry := q.pkgCache[pkgCacheKey(currentPkg, pkg)]
-		pkgToRules[pkg] = cacheEntry.rules
-		pkgToRuleToAlias[pkg] = cacheEntry.aliases
-	}
-
-	return pkgToRules, pkgToRuleToAlias, nil
-}
-
-func pkgCacheKey(currentPkg, pkg string) string {
-	return currentPkg + "|" + pkg
-}
-
-// dedupeLabels returns a new set of labels with no duplicates.
-func dedupeLabels(labels []string) []string {
-	addedLabels := make(map[string]bool)
-	var uniqueLabels []string
-	for _, label := range labels {
-		if _, added := addedLabels[label]; !added {
-			addedLabels[label] = true
-			uniqueLabels = append(uniqueLabels, label)
-		}
-	}
-	return uniqueLabels
-}
-
-// typeScriptRules returns all TypeScript rules in rules.
-func typeScriptRules(rules []*appb.Rule) []*appb.Rule {
-	var tsRules []*appb.Rule
-	for _, rule := range rules {
-		for _, supportedRuleClass := range []string{
-			"ts_library",
-			"ts_declaration",
-			"ng_module",
-		} {
-			if rule.GetRuleClass() == supportedRuleClass {
-				tsRules = append(tsRules, rule)
-				break
-			}
-		}
-	}
-	return tsRules
-}
-
-// resolveAgainstModuleRoot resolves imported against moduleRoot and moduleName.
-func resolveAgainstModuleRoot(rule *appb.Rule, imported string) string {
-	moduleName := stringAttribute(rule, "module_name")
-	if moduleName == "" {
-		return imported
-	}
-	if !pathStartsWith(imported, moduleName) {
-		return imported
-	}
-	// if module root is a file, remove the file extension, since it'll be added
-	// by possibleFilepaths below
-	moduleRoot := stripTSExtension(stringAttribute(rule, "module_root"))
-	_, pkg, _ := edit.ParseLabel(rule.GetName())
-
-	// resolve the import path against the module name and module root, ie if
-	// the import path is @foo/bar and there's a moduleName of @foo the resolved
-	// import path is location/of/foo/bar, or if there's also a moduleRoot of
-	// baz, the resolved import path is location/of/foo/baz/bar
-	//
-	// using strings.TrimPrefix for trimming the path is ok, since
-	// pathStartsWith already checked that moduleName is a proper prefix of
-	// i.importPath
-	return platform.Normalize(filepath.Join(pkg, moduleRoot, strings.TrimPrefix(imported, moduleName)))
-}
-
-// pathStartsWith checks if path starts with prefix, checking each path segment,
-// so that @angular/core starts with @angular/core, but @angular/core-bananas
-// does not
-func pathStartsWith(path, prefix string) bool {
-	pathParts := strings.Split(path, "/")
-	prefixParts := strings.Split(prefix, "/")
-
-	if len(prefixParts) > len(pathParts) {
-		return false
-	}
-
-	for i, prefixPart := range prefixParts {
-		if prefixPart != pathParts[i] {
-			return false
-		}
-	}
-
-	return true
-}
-
-// parsePackageName parses and returns the scope and package of imported. For
-// example, "@foo/bar" would have a scope of "@foo" and a package of "bar".
-func parsePackageName(imported string) (string, string) {
-	firstSlash := strings.Index(imported, "/")
-	if firstSlash == -1 {
-		return imported, ""
-	}
-	afterSlash := imported[firstSlash+1:]
-	if secondSlash := strings.Index(afterSlash, "/"); secondSlash > -1 {
-		return imported[:firstSlash], afterSlash[:secondSlash]
-	}
-	return imported[:firstSlash], afterSlash
-}
diff --git a/ts_auto_deps/analyze/loader_test.go b/ts_auto_deps/analyze/loader_test.go
deleted file mode 100644
index 5765129..0000000
--- a/ts_auto_deps/analyze/loader_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package analyze
-
-import (
-	"testing"
-
-	"github.com/golang/protobuf/proto"
-
-	appb "github.com/bazelbuild/buildtools/build_proto"
-)
-
-func TestResolveAgainstModuleRoot(t *testing.T) {
-	tests := []struct {
-		ruleLiteral string
-		imported    string
-		expected    string
-	}{
-		{
-			ruleLiteral: `name: "//a"
-			rule_class: "ts_library"`,
-			imported: "foo",
-			expected: "foo",
-		},
-		{
-			ruleLiteral: `name: "//b"
-			rule_class: "ts_library"
-			attribute: <
-				type: 4
-				name: "module_name"
-				string_value: "foo"
-			>`,
-			imported: "bar",
-			expected: "bar",
-		},
-		{
-			ruleLiteral: `name: "//c"
-			rule_class: "ts_library"
-			attribute: <
-				type: 4
-				name: "module_name"
-				string_value: "foo"
-			>`,
-			imported: "foo/bar",
-			expected: "c/bar",
-		},
-		{
-			ruleLiteral: `name: "//actual/loc:target"
-			rule_class: "ts_library"
-			attribute: <
-				type: 4
-				name: "module_name"
-				string_value: "foo/bar"
-			>
-			attribute: <
-			type: 4
-			name: "module_root"
-			string_value: "mod/root"
-			>`,
-			imported: "foo/bar/baz/bam",
-			expected: "actual/loc/mod/root/baz/bam",
-		},
-	}
-	for _, test := range tests {
-		rule, err := parseRuleLiteral(test.ruleLiteral)
-		if err != nil {
-			t.Errorf("isRuleAnAlias(%q): failed to parse literal: %s", test.ruleLiteral, err)
-			continue
-		}
-		if actual := resolveAgainstModuleRoot(rule, test.imported); actual != test.expected {
-			t.Errorf("resolveAgainstModuleRoot(%q): got %q, want %q", rule.GetName(), actual, test.expected)
-		}
-	}
-}
-
-func TestParsePackageName(t *testing.T) {
-	tests := []struct {
-		input, scope, pkg string
-	}{
-		{"foo/bar", "foo", "bar"},
-		{"foo/bar/baz", "foo", "bar"},
-		{"foo", "foo", ""},
-		{"", "", ""},
-	}
-	for _, test := range tests {
-		if scope, pkg := parsePackageName(test.input); scope != test.scope || pkg != test.pkg {
-			t.Errorf("moduleName(%q): got %q, %q, want %q, %q", test.input, scope, pkg, test.scope, test.pkg)
-		}
-	}
-}
-
-func parseRuleLiteral(literal string) (*appb.Rule, error) {
-	var rule appb.Rule
-	if err := proto.UnmarshalText(literal, &rule); err != nil {
-		return nil, err
-	}
-	return &rule, nil
-}
diff --git a/ts_auto_deps/main.go b/ts_auto_deps/main.go
deleted file mode 100644
index 553afbc..0000000
--- a/ts_auto_deps/main.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package main
-
-import (
-	"flag"
-	"fmt"
-	"os"
-
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/updater"
-)
-
-var (
-	isRoot = flag.Bool("root", false, "the given path is the root of a TypeScript project "+
-		"(generates ts_config and ts_development_sources targets).")
-	recursive = flag.Bool("recursive", false, "recursively update all packages under the given root.")
-	files     = flag.Bool("files", false, "treats arguments as file names. Filters .ts files, then runs on their dirnames.")
-)
-
-func usage() {
-	fmt.Fprintf(os.Stderr, `ts_auto_deps: generate BUILD rules for TypeScript sources.
-
-usage: %s [flags] [path...]
-
-ts_auto_deps generates and updates BUILD rules for each of the given package paths.
-Paths are expected to reside underneath the workspace root. If none is given,
-ts_auto_deps runs on the current working directory.
-
-For each of the given package paths, ts_auto_deps finds all TypeScript sources in the
-package and adds sources that are not currently built to the appropriate
-BUILD rule (ts_library or ts_declaration).
-
-If there is no matching BUILD rule, or no BUILD file, ts_auto_deps will create either.
-
-ts_auto_deps also updates BUILD rule dependencies ('deps') based on the source imports.
-
-Flags:
-`, os.Args[0])
-	flag.PrintDefaults()
-}
-
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-
-	paths, err := updater.Paths(*isRoot, *files, *recursive)
-	if err != nil {
-		platform.Error(err)
-	}
-
-	host := updater.New(false, false, updater.QueryBasedBazelAnalyze, updater.LocalUpdateFile)
-	if err := updater.Execute(host, paths, *isRoot, *recursive); err != nil {
-		platform.Error(err)
-	}
-}
diff --git a/ts_auto_deps/platform/BUILD.bazel b/ts_auto_deps/platform/BUILD.bazel
deleted file mode 100644
index 9e351ab..0000000
--- a/ts_auto_deps/platform/BUILD.bazel
+++ /dev/null
@@ -1,11 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "file.go",
-        "log.go",
-    ],
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps/platform",
-    visibility = ["//visibility:public"],
-)
diff --git a/ts_auto_deps/platform/file.go b/ts_auto_deps/platform/file.go
deleted file mode 100644
index 7df93d0..0000000
--- a/ts_auto_deps/platform/file.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package platform
-
-import (
-	"context"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-)
-
-const (
-	filePerms = 0666
-)
-
-var pathReplacer = strings.NewReplacer("\\", "/")
-
-// ReadFile reads the contents of name.
-func ReadFile(ctx context.Context, name string) ([]byte, error) {
-	return ioutil.ReadFile(name)
-}
-
-// ReadBytesFromFile reads bytes into the buffer provided, stopping when the
-// buffer is full.
-func ReadBytesFromFile(ctx context.Context, name string, buffer []byte) (int, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return 0, err
-	}
-	defer f.Close()
-
-	n, err := f.Read(buffer)
-	return n, err
-}
-
-// WriteFile writes data to filename.
-func WriteFile(ctx context.Context, filename string, data []byte) error {
-	return ioutil.WriteFile(filename, data, filePerms)
-}
-
-// Stat reads the file system information of name.
-func Stat(ctx context.Context, name string) (interface{}, error) {
-	return os.Stat(name)
-}
-
-// Glob returns all paths matching pattern.
-func Glob(ctx context.Context, pattern string) ([]string, error) {
-	return filepath.Glob(pattern)
-}
-
-// Normalize converts Windows path separators into POSIX
-func Normalize(path string) string {
-	return pathReplacer.Replace(path)
-}
diff --git a/ts_auto_deps/platform/log.go b/ts_auto_deps/platform/log.go
deleted file mode 100644
index 4fb889e..0000000
--- a/ts_auto_deps/platform/log.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package platform
-
-import (
-	"fmt"
-	"log"
-	"os"
-)
-
-// Infof prints a formatted message to stdout.
-func Infof(format string, args ...interface{}) {
-	fmt.Printf(format+"\n", args...)
-}
-
-// Error prints a series of args to stderr.
-func Error(args ...interface{}) {
-	fmt.Fprintln(os.Stderr, args...)
-}
-
-// Fatalf prints a formatted message to stderr. Panics after printing.
-func Fatalf(format string, v ...interface{}) {
-	log.Fatalf(format, v...)
-}
diff --git a/ts_auto_deps/platform/walk.go b/ts_auto_deps/platform/walk.go
deleted file mode 100644
index 05dd366..0000000
--- a/ts_auto_deps/platform/walk.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package platform
-
-import (
-	"os"
-	"path/filepath"
-)
-
-func Walk(root string, walkFn func(path string, typ os.FileMode) error) error {
-	return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
-		if err != nil {
-			return err
-		}
-		return walkFn(path, info.Mode())
-	})
-}
diff --git a/ts_auto_deps/proto/BUILD.bazel b/ts_auto_deps/proto/BUILD.bazel
deleted file mode 100644
index e7e793a..0000000
--- a/ts_auto_deps/proto/BUILD.bazel
+++ /dev/null
@@ -1,22 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-
-proto_library(
-    name = "bazel_analyze_proto",
-    srcs = ["analyze_result.proto"],
-    visibility = ["//visibility:public"],
-)
-
-go_proto_library(
-    name = "bazel_analyze_go_proto",
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps/proto",
-    proto = ":bazel_analyze_proto",
-    visibility = ["//visibility:public"],
-)
-
-go_library(
-    name = "go_default_library",
-    embed = [":bazel_analyze_go_proto"],
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps/proto",
-    visibility = ["//visibility:public"],
-)
diff --git a/ts_auto_deps/proto/analyze_result.proto b/ts_auto_deps/proto/analyze_result.proto
deleted file mode 100644
index 49ee500..0000000
--- a/ts_auto_deps/proto/analyze_result.proto
+++ /dev/null
@@ -1,98 +0,0 @@
-syntax = "proto2";
-
-package bazel_analyze;
-
-// A DependencyGroup represents a list of alternatives for satisfying
-// a missing dependency.
-message DependencyGroup {
-  // Represents the visibility status of this dependency group. All the
-  // dependencies have the same visibility status indicated by the visibility
-  // field. Producers of this message (i.e. checkdeps) will ensure that
-  // the invariant is true.
-  enum Visibility {
-    // Visibility was not considered. (Default)
-    UNKNOWN = 0;
-    // All the alternatives are visible
-    ALL_VISIBLE = 1;
-    // All the alternatives are invisible
-    ALL_INVISIBLE = 2;
-  }
-
-  repeated string dependency = 1;
-  optional Visibility visibility = 2 [default = UNKNOWN];
-  // The set of import paths for which any of these dependencies can provide.
-  // It is legal for there to be multiple entries there (in practice it is
-  // not very common). This happens if the dependencies required by one
-  // import_path is a subset of the other. In that case, the smaller set of
-  // dependencies is populated in dependency field, and both import_path's are
-  // listed here.
-  repeated string import_path = 3;
-}
-
-// Represents information about arbitrary non-deps attributes.
-message AttributeReport {
-  // Name of the attribute (e.g. "runtime_deps").
-  optional string attribute = 1;
-  // Attribute value that is required but missing.
-  repeated string missing_value = 2;
-  // Attribute value that is declared but not needed.
-  repeated string unnecessary_value = 3;
-}
-
-// The result of checking a single build rule (called X in comments
-// below) for missing or unnecessary dependencies.  Produced by
-// java/com/google/devtools/build/checkbuilddeps (which for external
-// users means it's produced by bazel analyze).
-message DependencyReport {
-  required string rule = 1;  // Name of rule X, in canonical google3 format.
-
-  // Names of targets that are, or should be, declared as dependencies
-  // by rule X.  Some need to be declared and some don't; in some
-  // cases it is impossible to tell by static analysis.  Each is the
-  // full canonical name of the target, i.e. //x/y:z, or the shorthand
-  // form if the target name equals the package name, i.e. //x/y
-  // (shorthand for //x/y:y).
-
-  // Declared and needed. Removing these dependencies should break the build.
-  repeated string necessary_dependency = 2;
-
-  // Declared but not needed. Removing these dependencies should not break
-  // the build.
-  repeated string unnecessary_dependency = 3;
-
-  // Can't tell. These may be dependencies where no corresponding imports
-  // were found, but alwayslink=1.
-  repeated string ambiguous_dependency = 4;
-
-  // Needed but not declared. If there are imports which can be satisfied
-  // by more than one dependency declared in a best-matching package, list
-  // all of them. If this list is not empty, we expect the build to break.
-  repeated DependencyGroup missing_dependency_group = 8;
-
-  // Files/classes that a source file imports, but for which no
-  // appropriate dependency could be found. We expect the build to break
-  // if this list is not empty.
-  // NOTE: If there are unreseolved imports, it may indicate that
-  // analysis failed to connect a declared dependency with a
-  // corresponding import statement, and so you may want to have less
-  // faith in the unnecessary_dependency field (though, in general,
-  // rules in unnecessary_dependency are still PROBABLY unnecessary).
-  repeated string unresolved_import = 7;
-
-  // Source files that are inputs to the rule but cannot be found.
-  // Values are absolute labels, e.g. '//foo:bar/baz.c'.
-  repeated string missing_source_file = 13;
-
-  // General-purpose feedback messages from the dependency checker
-  // (errors, warnings, any kind of info).
-  repeated string feedback = 6;
-
-  // Indicates whether the dependency analysis completed without errors.
-  optional bool successful = 10 [default = true];
-}
-
-// Aggregate DependencyReports for multiple analysis
-// targets - used to support bazel analyze --analysis_output=proto
-message AnalyzeResult {
-  repeated DependencyReport dependency_report = 1;
-}
diff --git a/ts_auto_deps/updater/BUILD.bazel b/ts_auto_deps/updater/BUILD.bazel
deleted file mode 100644
index 53e319c..0000000
--- a/ts_auto_deps/updater/BUILD.bazel
+++ /dev/null
@@ -1,29 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["updater.go"],
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps/updater",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//ts_auto_deps/analyze:go_default_library",
-        "//ts_auto_deps/platform:go_default_library",
-        "//ts_auto_deps/proto:go_default_library",
-        "//ts_auto_deps/workspace:go_default_library",
-        "@com_github_bazelbuild_buildtools//build:go_default_library",
-        "@com_github_bazelbuild_buildtools//edit:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-        "@com_github_mattn_go_isatty//:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = ["updater_test.go"],
-    embed = [":go_default_library"],
-    deps = [
-        "//ts_auto_deps/proto:go_default_library",
-        "@com_github_bazelbuild_buildtools//build:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-    ],
-)
diff --git a/ts_auto_deps/updater/test_register.go b/ts_auto_deps/updater/test_register.go
deleted file mode 100644
index 0f51e63..0000000
--- a/ts_auto_deps/updater/test_register.go
+++ /dev/null
@@ -1,259 +0,0 @@
-package updater
-
-import (
-	"context"
-	"fmt"
-	"path/filepath"
-
-	"github.com/bazelbuild/buildtools/build"
-	"github.com/bazelbuild/buildtools/edit"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-)
-
-// isAllTestLibrary identifies testonly ts_libraries named "all_tests".  Taze
-// will register tests with these rules instead of
-// ts_config/ts_development_sources rules to allow users to set up their builds
-// differently.
-func isAllTestLibrary(bld *build.File, r *build.Rule) bool {
-	if !ruleMatches(bld, r, "ts_library", ruleTypeTest) {
-		return false
-	}
-
-	if r.Name() != "all_tests" {
-		return false
-	}
-
-	return true
-}
-
-func getAllTestLibraries(bld *build.File) []*build.Rule {
-	var allTestRules []*build.Rule
-	for _, r := range buildRules(bld, "ts_library") {
-		if isAllTestLibrary(bld, r) {
-			allTestRules = append(allTestRules, r)
-		}
-	}
-	return allTestRules
-}
-
-// RegisterTestRules registers ts_library test targets with the project's
-// ts_config and ts_development_sources rules.  It may also register the tests
-// with a testonly ts_library named "all_tests", which allows users to set up
-// their own BUILD layout.  It's separated from UpdateBUILD since it's
-// non-local, multiple packages may all need to make writes to the same
-// ts_config.  It returns a set of the paths for the packages that were updated.
-func (upd *Updater) RegisterTestRules(ctx context.Context, paths ...string) (bool, map[string]bool, error) {
-	reg := &buildRegistry{make(map[string]*build.File), make(map[*build.File]bool)}
-	var g3root string
-	updatedAncestorPackages := make(map[string]bool)
-	for _, path := range paths {
-		// declare variables manually so that g3root doesn't get overwritten by a :=
-		// declaration
-		var err error
-		var buildPath string
-		g3root, buildPath, _, err = getBUILDPath(ctx, path)
-		if err != nil {
-			return false, nil, err
-		}
-		bld, err := reg.readBUILD(ctx, g3root, buildPath)
-		if err != nil {
-			return false, nil, err
-		}
-		for _, tr := range getRules(bld, "ts_library", ruleTypeTest) {
-			// don't register all_test libraries themselves
-			if isAllTestLibrary(bld, tr) {
-				continue
-			}
-			platform.Infof("Registering test rule in closest ts_config & ts_development_sources")
-			target := AbsoluteBazelTarget(bld, tr.Name())
-			ancestorBuild, err := reg.registerTestRule(ctx, bld, tsConfig, g3root, target)
-			if err != nil {
-				return false, nil, err
-			}
-			if ancestorBuild != "" {
-				updatedAncestorPackages[ancestorBuild] = true
-			}
-			// NodeJS rules should not be added to ts_development_sources automatically, because
-			// they typically do not run in the browser.
-			if tr.AttrString("runtime") != "nodejs" {
-				ancestorBuild, err := reg.registerTestRule(ctx, bld, tsDevSrcs, g3root, target)
-				if err != nil {
-					return false, nil, err
-				}
-				if ancestorBuild != "" {
-					updatedAncestorPackages[ancestorBuild] = true
-				}
-			}
-		}
-	}
-
-	updated := false
-	for b := range reg.filesToUpdate {
-		fmt.Printf("Registered test(s) in %s\n", b.Path)
-		fileChanged, err := upd.maybeWriteBUILD(ctx, filepath.Join(g3root, b.Path), b)
-		if err != nil {
-			return false, nil, err
-		}
-		updated = updated || fileChanged
-	}
-
-	return updated, updatedAncestorPackages, nil
-}
-
-// buildRegistry buffers reads and writes done while registering ts_libraries
-// with ts_config and ts_development_sources rules, so that registers from
-// multiple packages all get applied at once.
-type buildRegistry struct {
-	bldFiles      map[string]*build.File
-	filesToUpdate map[*build.File]bool
-}
-
-func (reg *buildRegistry) readBUILD(ctx context.Context, workspaceRoot, buildFilePath string) (*build.File, error) {
-	normalizedG3Path, err := getWorkspaceRelativePath(workspaceRoot, buildFilePath)
-	if err != nil {
-		return nil, err
-	}
-
-	if bld, ok := reg.bldFiles[normalizedG3Path]; ok {
-		return bld, nil
-	}
-
-	bld, err := readBUILD(ctx, buildFilePath, normalizedG3Path)
-	if err != nil {
-		return nil, err
-	}
-	if bld == nil {
-		// The BUILD file didn't exist, so create a new, empty one.
-		bld = &build.File{Path: normalizedG3Path, Type: build.TypeBuild}
-	}
-
-	reg.bldFiles[normalizedG3Path] = bld
-
-	return bld, nil
-}
-
-func (reg *buildRegistry) registerForPossibleUpdate(bld *build.File) {
-	reg.filesToUpdate[bld] = true
-}
-
-type registerTarget int
-
-const (
-	tsConfig registerTarget = iota
-	tsDevSrcs
-)
-
-func (rt registerTarget) kind() string {
-	if rt == tsConfig {
-		return "ts_config"
-	}
-
-	return "ts_development_sources"
-}
-
-func (rt registerTarget) ruleType() ruleType {
-	if rt == tsConfig {
-		return ruleTypeAny
-	}
-
-	return ruleTypeTest
-}
-
-// registerTestRule searches ancestor packages for a rule matching the register
-// target and adds the given target to it. If an all_tests library is found, the
-// rule is registered with it, instead of specified register target. Prints a
-// warning if no rule is found, but only returns an error if adding the
-// dependency fails.
-func (reg *buildRegistry) registerTestRule(ctx context.Context, bld *build.File, rt registerTarget, g3root, target string) (string, error) {
-	if buildHasDisableTaze(bld) {
-		return "", nil
-	}
-
-	var ruleToRegister *build.Rule
-	for _, r := range bld.Rules("") {
-		if isAllTestLibrary(bld, r) {
-			if hasDependency(bld, r, target) {
-				return "", nil
-			}
-
-			// an all_tests library takes presidence over a registerTarget, and there
-			// can only be one, since there can only be one rule with a given name, so
-			// can just break after finding
-			ruleToRegister = r
-			break
-		}
-		if ruleMatches(bld, r, rt.kind(), rt.ruleType()) {
-			if hasDependency(bld, r, target) {
-				return "", nil
-			}
-
-			// keep overwriting ruleToRegister so the last match in the BUILD gets
-			// used
-			ruleToRegister = r
-		}
-	}
-
-	if ruleToRegister != nil {
-		addDep(bld, ruleToRegister, target)
-		reg.registerForPossibleUpdate(bld)
-		return filepath.Dir(bld.Path), nil
-	}
-
-	parentDir := filepath.Dir(filepath.Dir(bld.Path))
-	for parentDir != "." && parentDir != "/" {
-		buildFile := filepath.Join(g3root, parentDir, "BUILD")
-		if _, err := platform.Stat(ctx, buildFile); err == nil {
-			parent, err := reg.readBUILD(ctx, g3root, buildFile)
-			if err != nil {
-				return "", err
-			}
-			return reg.registerTestRule(ctx, parent, rt, g3root, target)
-		}
-		parentDir = filepath.Dir(parentDir)
-	}
-	fmt.Printf("WARNING: no %s rule in parent packages of %s to register with.\n",
-		rt.kind(), target)
-	return "", nil
-}
-
-var wellKnownBuildRules = []struct {
-	name     string
-	attrName string
-}{
-	{
-		name:     "karma_polymer_test",
-		attrName: "test_ts_deps",
-	},
-	{
-		name:     "wct_closure_test_suite",
-		attrName: "js_deps",
-	},
-	{
-		name:     "jasmine_node_test",
-		attrName: "deps",
-	},
-	{
-		name:     "karma_web_test_suite",
-		attrName: "deps",
-	},
-	{
-		name:     "boq_jswire_test_library",
-		attrName: "deps",
-	},
-}
-
-// isRegisteredWithAlternateTestRule returns true if the rule is already
-// registered with a well known test rule, such as karma_polymer_test,
-// wct_closure_test_suite or jasmine_node_test.
-func isRegisteredWithAlternateTestRule(bld *build.File, r *build.Rule, dep string) bool {
-	pkg := filepath.Dir(bld.Path)
-	for _, wkbr := range wellKnownBuildRules {
-		if isKind(r, wkbr.name) {
-			testTsDeps := r.Attr(wkbr.attrName)
-			if edit.ListFind(testTsDeps, dep, pkg) != nil {
-				return true
-			}
-		}
-	}
-	return false
-}
diff --git a/ts_auto_deps/updater/updater.go b/ts_auto_deps/updater/updater.go
deleted file mode 100644
index f606e5b..0000000
--- a/ts_auto_deps/updater/updater.go
+++ /dev/null
@@ -1,1340 +0,0 @@
-// Package updater implements the main logic of the ts_auto_deps command. It reads BUILD files,
-// discovers TypeScript sources, uses `bazel analyze` to update import/dependency information,
-// and then modifies the BUILD file accordingly.
-package updater
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"io"
-	"os"
-	"path/filepath"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"flag"
-	"github.com/bazelbuild/buildtools/build"
-	"github.com/bazelbuild/buildtools/edit"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/analyze"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/platform"
-	"github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace"
-	"github.com/golang/protobuf/proto"
-	"github.com/mattn/go-isatty"
-
-	arpb "github.com/bazelbuild/rules_typescript/ts_auto_deps/proto"
-)
-
-var bazelErrorRE = regexp.MustCompile(`ERROR: ([^:]+):(\d+):\d+:`)
-
-// New creates a new updater from the given arguments. One updater can be used
-// to update many packages, repeatedly, but not concurrently.
-// bazelAnalyze and updateFile can be passed in to handle ts_auto_deps operation in
-// different environments and for fakes in tests.
-func New(removeUnusedDeclarations bool, updateComments bool, bazelAnalyze BazelAnalyzer, updateFile UpdateFile) *Updater {
-	return &Updater{removeUnusedDeclarations, updateComments, bazelAnalyze, updateFile}
-}
-
-// UpdateFile updates the contents of filePath. Implementations may postpone or batch actually writing the given file, i.e.
-// a subsequent read may return stale contents.
-type UpdateFile func(ctx context.Context, filePath string, contents string) error
-
-// LocalUpdateFile simply writes to the given file.
-func LocalUpdateFile(ctx context.Context, filePath string, contents string) error {
-	return platform.WriteFile(ctx, filePath, []byte(contents))
-}
-
-// BazelAnalyzer is a function that executes bazel analyze for the given
-// absolute build file path and bazel targets, and returns the raw analysis
-// result proto, or an error if the analyze call failed.
-// It's used to abstract over execution using rabbit vs local execution.
-// Returns the main output (serialized AnalysisResult proto), any error
-// messages, or an error.
-type BazelAnalyzer func(buildFilePath string, targets []string) ([]byte, []byte, error)
-
-// Updater encapsulates configuration for the ts_auto_deps process.
-type Updater struct {
-	removeUnusedDeclarations bool
-	updateComments           bool
-	bazelAnalyze             BazelAnalyzer
-	updateFile               UpdateFile
-}
-
-func attrTruthy(r *build.Rule, attr string) bool {
-	attrVal := r.AttrLiteral(attr)
-	return attrVal == "True" || attrVal == "1"
-}
-
-// Matches the warning TypeScriptRuleChecker prints for unused ts_declarations.
-// TODO(martinprobst): in the long term, this should become the default and TypeScriptRuleChecker should no longer special case ts_declaration.
-var unusedDeclarationRE = regexp.MustCompile(
-	`WARNING: [^:]+:\d+:(?:\d+:)? keeping possibly used ts_declaration '([^']+)'`)
-
-// GarbledBazelResponseError signals to callers that the proto returned by bazel
-// analyze was garbled, and couldn't be unmarshalled.
-// TODO(lucassloan): remove when b/112891536 is fixed
-// Build Rabbit rewrites paths produced by bazel, which garbles the error
-// messages from bazel analyze, since they're encoded in protobufs.
-type GarbledBazelResponseError struct {
-	Message string
-}
-
-func (g *GarbledBazelResponseError) Error() string {
-	return g.Message
-}
-
-// runBazelAnalyze executes the `bazel analyze` command and extracts reports.
-// It returns the dependency report with rule names referring to rules *before*
-// macro expansion, or an error. runBazelAnalyze uses the given `analyze`
-// function to actually run the `bazel analyze` operation, which allows
-// exchanging it for a different implementation in the ts_auto_deps presubmit service.
-func (upd *Updater) runBazelAnalyze(buildFilePath string, bld *build.File, rules []*build.Rule) ([]*arpb.DependencyReport, error) {
-	var targets []string
-	for _, r := range rules {
-		fullTarget := AbsoluteBazelTarget(bld, r.Name())
-		targets = append(targets, fullTarget)
-	}
-	out, stderr, err := upd.bazelAnalyze(buildFilePath, targets)
-	if err != nil {
-		return nil, err
-	}
-
-	var res arpb.AnalyzeResult
-	if err := proto.Unmarshal(out, &res); err != nil {
-		// TODO(lucassloan): remove when b/112891536 is fixed
-		// Build Rabbit rewrites paths produced by bazel, which garbles the error
-		// messages from bazel analyze, since they're encoded in protobufs.
-		return nil, &GarbledBazelResponseError{fmt.Sprintf("failed to unmarshal analysis result: %v\nin: %q", err, string(out))}
-	}
-	platform.Infof("analyze result %v", res)
-	reports := res.GetDependencyReport()
-	if len(targets) != len(reports) {
-		if len(stderr) > 0 {
-			// TODO(b/73321854): pretend second rule has a syntactical error, so bazel analyze produces no
-			// report for it, but also doesn't return an error code. Remove workaround once fixed.
-			return nil, fmt.Errorf("parsing reports failed (%d reports for %s):\n%s",
-				len(reports), targets, stderr)
-		}
-		return nil, fmt.Errorf("parsing reports failed (%d reports for %s) in output: %s",
-			len(reports), targets, out)
-	}
-	if upd.removeUnusedDeclarations {
-		for _, report := range reports {
-			for _, fb := range report.GetFeedback() {
-				m := unusedDeclarationRE.FindStringSubmatch(fb)
-				if m == nil {
-					continue
-				}
-				target := m[1]
-				platform.Infof("Removing (possibly) unused ts_declaration dependency %q", target)
-				// TODO(martinprobst): this warning is to educate users after changing removeUnusedDeclarations to true by default.
-				// Once existing code is fixed, this constitutes normal operation, and the logging below should be dropped.
-				fmt.Fprintf(os.Stderr, "WARNING: removing apparently unused ts_declaration() dependency from %q.\n", report.GetRule())
-
-				report.UnnecessaryDependency = append(report.UnnecessaryDependency, target)
-			}
-		}
-	}
-	return reports, nil
-}
-
-func spin(prefix string) chan<- struct{} {
-	done := make(chan struct{})
-	// Check for cygwin, important for Windows compatibility
-	if !isatty.IsTerminal(os.Stderr.Fd()) || !isatty.IsCygwinTerminal(os.Stdout.Fd()) {
-		return done
-	}
-	go func() {
-		// Wait a bit before starting to print to avoid flashing a spinner unnecessarily.
-		time.Sleep(100 * time.Millisecond)
-		ticker := time.NewTicker(100 * time.Millisecond)
-		defer ticker.Stop()
-		i := 0
-		str := []rune(`⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏`)
-		for {
-			select {
-			case <-done:
-				fmt.Fprint(os.Stderr, "\r")
-				for i := 0; i < len(prefix)+2; i++ {
-					fmt.Fprint(os.Stderr, " ")
-				}
-				fmt.Fprint(os.Stderr, "\r")
-				return
-			case <-ticker.C:
-				fmt.Fprintf(os.Stderr, "\r%s %s", prefix, string(str[i]))
-				i = (i + 1) % len(str)
-			}
-		}
-	}()
-	return done
-}
-
-// readBUILD loads the BUILD file, if present, or returns a nil pointer, if not.
-// buildFilePath is relative to CWD, and workspaceRelativePath is relative to
-// the workspace root (the directory containing the WORKSPACE file).
-func readBUILD(ctx context.Context, buildFilePath, workspaceRelativePath string) (*build.File, error) {
-	data, err := platform.ReadFile(ctx, buildFilePath)
-	if err != nil {
-		if os.IsNotExist(err) {
-			return nil, nil
-		}
-		return nil, err
-	}
-	bld, err := build.ParseBuild(workspaceRelativePath, data)
-	if err != nil {
-		if parseErr, ok := err.(build.ParseError); ok {
-			return nil, &AnalysisFailedError{
-				[]AnalysisFailureCause{
-					AnalysisFailureCause{
-						Message: parseErr.Error(),
-						Path:    parseErr.Filename,
-						Line:    parseErr.Pos.Line,
-					},
-				},
-			}
-
-		}
-
-		// wasn't an error we know how to parse
-		return nil, err
-	}
-	return bld, nil
-}
-
-type srcSet map[string]bool
-
-type globResult struct {
-	srcs srcSet
-	err  error
-}
-
-// globSources finds sources in path with any of the given extensions.
-// It also filters out temporary files, dangling symlinks, and symlinks into bazel-bin specifically.
-// It returns file names relative to path.
-func globSources(ctx context.Context, path string, extensions []string) (srcSet, error) {
-	var allSourcePaths []string
-	for _, extension := range extensions {
-		pattern := "*." + extension
-		matched, err := platform.Glob(ctx, filepath.Join(path, pattern))
-		if err != nil {
-			return nil, fmt.Errorf("glob(%s): %s", pattern, err)
-		}
-		allSourcePaths = append(allSourcePaths, matched...)
-	}
-	srcs := make(srcSet)
-	for _, p := range allSourcePaths {
-		fileName := filepath.Base(p)
-		if isTempFile(fileName) {
-			continue // Ignore editor swap/backup files.
-		}
-		// Try platform.Stat as a fallback, for Google file systems.
-		_, err := platform.Stat(ctx, p)
-		if os.IsNotExist(err) {
-			platform.Infof("platform.Glob returned non-existent file (dangling symlink?). Ignoring %q.", p)
-			continue
-		}
-		if err != nil {
-			return nil, fmt.Errorf("cannot stat platform.Glob result %q: %v", p, err)
-		}
-		isMpeg, err := IsMpegTS(ctx, p)
-		if err != nil {
-			return nil, err
-		}
-		if isMpeg {
-			continue
-		}
-		p, err := filepath.Rel(path, p)
-		if err != nil {
-			return nil, fmt.Errorf("filepath.Rel(%s, %s): %v", path, p, err)
-		}
-		srcs[p] = true
-	}
-	return srcs, nil
-}
-
-// IsMpegTS checks if a ".ts" file is an MPEG transport stream.  Taze shouldn't
-// treat them as TypeScript files.
-func IsMpegTS(ctx context.Context, path string) (bool, error) {
-	var content [200]byte
-	n, err := platform.ReadBytesFromFile(ctx, path, content[:])
-	if err != nil && err != io.EOF {
-		return false, err
-	}
-
-	// MPEG TS' frame format starts with 0x47 every 189 bytes - detect that and return.
-	isMpeg := n > 188 && content[0] == 0x47 && content[188] == 0x47
-	return isMpeg, nil
-}
-
-func isTempFile(fileName string) bool {
-	return strings.HasPrefix(fileName, ".") || strings.HasSuffix(fileName, ".swp") ||
-		strings.HasSuffix(fileName, "~")
-}
-
-// updateSources adds any srcs that are not in some rule to the last ts_* rule
-// in the package, or create a new rule for them.
-func updateSources(bld *build.File, srcs srcSet) {
-	removeSourcesUsed(bld, "ts_library", "srcs", srcs)
-	removeSourcesUsed(bld, "ts_declaration", "srcs", srcs)
-
-	if len(srcs) == 0 {
-		return
-	}
-
-	// Sort the remaining sources for reproducibility (sadly Go has no LinkedHashSet)
-	var srcSlice []string
-	for s := range srcs {
-		srcSlice = append(srcSlice, s)
-	}
-	sort.Strings(srcSlice)
-
-	pkgName := filepath.Base(filepath.Dir(bld.Path))
-	platform.Infof("Adding new sources to targets in %q: %q", pkgName, srcSlice)
-	for _, s := range srcSlice {
-		var r *build.Rule
-		ruleName := pkgName
-		if strings.HasSuffix(s, ".d.ts") {
-			r = getOrCreateRule(bld, ruleName+"_dts", "ts_declaration", ruleTypeRegular)
-		} else {
-			rt := determineRuleType(bld.Path, s)
-			r = getOrCreateRule(bld, ruleName, "ts_library", rt)
-		}
-		addToSrcsClobbering(bld, r, s)
-	}
-}
-
-// Adds the given value to the srcs attribute on the build rule. Clobbers any
-// existing values for srcs that are not a list.
-func addToSrcsClobbering(bld *build.File, r *build.Rule, s string) {
-	value := r.Attr("srcs")
-	switch value.(type) {
-	case nil, *build.ListExpr:
-		// expected - a list of files (labels) or absent.
-	default:
-		// Remove any glob calls, variables, etc. ts_auto_deps uses explicit source lists.
-		fmt.Fprintf(os.Stderr, "WARNING: clobbering non-list srcs attribute on %s\n",
-			AbsoluteBazelTarget(bld, r.Name()))
-		r.DelAttr("srcs")
-	}
-	val := &build.StringExpr{Value: s}
-	edit.AddValueToListAttribute(r, "srcs", "", val, nil)
-}
-
-var testingRegexp = regexp.MustCompile(`\btesting\b`)
-
-func determineRuleType(path, s string) ruleType {
-	if strings.HasSuffix(s, "_test.ts") || strings.HasSuffix(s, "_test.tsx") {
-		return ruleTypeTest
-	}
-
-	return ruleTypeRegular
-}
-
-// AnalysisFailedError is returned by ts_auto_deps when the underlying analyze operation
-// fails, e.g. because the BUILD files have syntactical errors.
-type AnalysisFailedError struct {
-	Causes []AnalysisFailureCause
-}
-
-// AnalysisFailureCause gives (one of) the reasons analysis failed, along with
-// the path and line that caused the failure (if available).
-type AnalysisFailureCause struct {
-	Message string
-	// workspace path of the file on which analysis failed ie foo/bar/baz.ts, not
-	// starting with google3/
-	Path string
-	// 1-based line on which analysis failed
-	Line int
-}
-
-func (a *AnalysisFailedError) Error() string {
-	var messages []string
-	for _, c := range a.Causes {
-		messages = append(messages, c.Message)
-	}
-	return strings.Join(messages, "\n")
-}
-
-// updateDeps adds missing dependencies and removes unnecessary dependencies
-// for the targets in the given DependencyReports to the build rules in bld.
-func updateDeps(bld *build.File, reports []*arpb.DependencyReport) error {
-	// First, check *all* reports on whether they were successful, so that users
-	// get the complete set of errors at once.
-	var errors []AnalysisFailureCause
-	for _, report := range reports {
-		if !report.GetSuccessful() {
-			for _, fb := range report.GetFeedback() {
-				msg := fmt.Sprintf("dependency analysis failed for %s:\n%s",
-					report.GetRule(), fb)
-
-				m := bazelErrorRE.FindStringSubmatch(fb)
-				if m == nil {
-					// error message didn't contain file and line number, so just use the
-					// path of the BUILD file that was analyzed
-					errors = append(errors, AnalysisFailureCause{Message: msg, Path: bld.Path})
-					continue
-				}
-
-				file := m[1]
-				line, err := strconv.Atoi(m[2])
-				if err != nil {
-					return err
-				}
-
-				errors = append(errors, AnalysisFailureCause{msg, file, line})
-			}
-		}
-	}
-	if len(errors) > 0 {
-		return &AnalysisFailedError{errors}
-	}
-
-	pkg := filepath.Dir(bld.Path)
-	for _, report := range reports {
-		platform.Infof("Applying report: %s", report.String())
-		fullTarget := report.GetRule()
-		targetName := fullTarget[strings.LastIndex(fullTarget, ":")+1:]
-		r := edit.FindRuleByName(bld, targetName)
-		if r == nil {
-			return fmt.Errorf("could not find rule from report %v", targetName)
-		}
-		for _, md := range report.MissingDependencyGroup {
-			for _, d := range md.Dependency {
-				d = AbsoluteBazelTarget(bld, d)
-				if d == fullTarget {
-					return &AnalysisFailedError{
-						[]AnalysisFailureCause{
-							AnalysisFailureCause{
-								Message: fmt.Sprintf("target %s depends on itself. "+
-									"Maybe you have an incorrect `// from %s` comment, or need to split application "+
-									"entry point (main.ts) and ng_module() rule?", d, d),
-								Path: bld.Path,
-							},
-						},
-					}
-				}
-				platform.Infof("Adding dependency on %s to %s\n", d, fullTarget)
-				addDep(bld, r, d)
-			}
-		}
-		hadUnresolved := len(report.UnresolvedImport) > 0
-		if hadUnresolved {
-			return &AnalysisFailedError{
-				[]AnalysisFailureCause{
-					AnalysisFailureCause{
-						Message: 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")),
-						Path: bld.Path,
-					},
-				},
-			}
-		}
-		for _, d := range report.UnnecessaryDependency {
-			platform.Infof("Removing dependency on %s from %s\n", d, fullTarget)
-			edit.ListAttributeDelete(r, "deps", d, pkg)
-		}
-		for _, s := range report.MissingSourceFile {
-			platform.Infof("Removing missing source %s from %s\n", s, fullTarget)
-			edit.ListAttributeDelete(r, "srcs", s, pkg)
-		}
-	}
-	return nil
-}
-
-// maybeWriteBUILD checks if the given file needs updating, i.e. whether the
-// canonical serialized form of bld has changed from the file contents on disk.
-// If so, writes the file and returns true, returns false otherwise.
-func (upd *Updater) maybeWriteBUILD(ctx context.Context, path string, bld *build.File) (bool, error) {
-	ri := &build.RewriteInfo{}
-	build.Rewrite(bld, ri)
-	platform.Infof("Formatted %s: %s\n", path, ri)
-	newContent := build.Format(bld)
-	oldContent, err := platform.ReadFile(ctx, path)
-	if err != nil {
-		if !os.IsNotExist(err) {
-			return false, err
-		} else if len(newContent) == 0 {
-			// The BUILD file does not exist, and the newly created file has no content.
-			// Treat this as equivalent, and do not create a new BUILD file.
-			return false, nil
-		}
-		// Fall through to write a new file.
-	} else if bytes.Equal(oldContent, newContent) {
-		// Compare contents, only update if changed.
-		return false, nil
-	}
-	if err := upd.updateFile(ctx, path, string(newContent)); err != nil {
-		return false, fmt.Errorf("failed to update %q: %v", path, err)
-	}
-	return true, nil
-}
-
-// getWorkspaceRelativePath takes a buildFilePath that's relative to the working
-// directory, and returns a path to the BUILD file that's relative to the
-// workspaceRoot (the absolute path of the directory containing the WORKSPACE
-// file).
-func getWorkspaceRelativePath(workspaceRoot, buildFilePath string) (string, error) {
-	absPath, err := filepath.Abs(buildFilePath)
-	if err != nil {
-		return "", err
-	}
-	workspaceRelativePath, err := filepath.Rel(workspaceRoot, absPath)
-	if err != nil {
-		return "", err
-	}
-	platform.Normalize(workspaceRelativePath)
-
-	return workspaceRelativePath, nil
-}
-
-// getBUILDPath takes in a package or BUILD file path, and returns the path of
-// the workspace root (the absolute path of the directory containing the
-// WORKSPACE file), the BUILD file path relative to the working directory, and
-// the BUILD file path relative to the workspace root.
-func getBUILDPath(ctx context.Context, path string) (string, string, string, error) {
-	path = strings.TrimSuffix(path, "/BUILD") // Support both package paths and BUILD files
-	if _, err := platform.Stat(ctx, path); os.IsNotExist(err) {
-		return "", "", "", err
-	}
-	buildFilePath := filepath.Join(path, "BUILD")
-	workspaceRoot, err := workspace.Root(buildFilePath)
-	if err != nil {
-		return "", "", "", err
-	}
-
-	workspaceRelativePath, err := getWorkspaceRelativePath(workspaceRoot, buildFilePath)
-	if err != nil {
-		return "", "", "", err
-	}
-
-	return workspaceRoot, buildFilePath, workspaceRelativePath, nil
-}
-
-// isTazeDisabledInPackage checks the BUILD file, or if the BUILD doesn't exist,
-// the nearest ancestor BUILD file for a disable_ts_auto_deps() rule.
-func isTazeDisabledInPackage(ctx context.Context, g3root, buildFilePath, workspaceRelativePath string, bld *build.File) (bool, error) {
-	if bld == nil {
-		// Make sure ts_auto_deps hasn't been disabled in the next closest ancestor package.
-		ancestor, err := FindBUILDFile(ctx, make(map[string]*build.File), g3root, filepath.Dir(workspaceRelativePath))
-		if _, ok := err.(*noAncestorBUILDError); ok {
-			platform.Infof("Could not find any ancestor BUILD for %q, continuing with a new BUILD file",
-				buildFilePath)
-			return false, nil
-		} else if err != nil {
-			return false, err
-		} else if buildHasDisableTaze(ancestor) {
-			fmt.Printf("ts_auto_deps disabled below %q\n", ancestor.Path)
-			return true, nil
-		} else {
-			platform.Infof("BUILD file missing and ts_auto_deps is enabled below %q. Creating new BUILD file.",
-				ancestor.Path)
-			return false, nil
-		}
-	}
-
-	if buildHasDisableTaze(bld) {
-		fmt.Printf("ts_auto_deps disabled on %q\n", buildFilePath)
-		return true, nil
-	}
-
-	return false, nil
-}
-
-// SubdirectorySourcesError is returned when ts_auto_deps detects a BUILD file
-// that references sources in another directory, either in the directory
-// being ts_auto_depsd, or in a super directory.
-type SubdirectorySourcesError struct{}
-
-func (a *SubdirectorySourcesError) Error() string {
-	return "ts_auto_deps doesn't handle referencing sources in another directory " +
-		"- to use ts_auto_deps, migrate to having a BUILD file in every directory. " +
-		"For more details, see go/ts_auto_deps#subdirectory-sources"
-}
-
-// hasSubdirectorySources checks if the BUILD file has ts_libraries that contain
-// source files from subdirectories of the directory with the BUILD. ie foo/BUILD
-// has a src foo/bar/baz.ts, in the subdirectory foo/bar.
-func hasSubdirectorySources(bld *build.File) bool {
-	for _, rule := range buildRules(bld, "ts_library") {
-		srcs := rule.AttrStrings("srcs")
-		if srcs != nil {
-			for _, s := range srcs {
-				if strings.Contains(s, "/") {
-					return true
-				}
-			}
-		} else {
-			// srcs wasn't a list, check for a glob over subdirectory soruces
-			srcExp := rule.Attr("srcs")
-			call, ok := srcExp.(*build.CallExpr)
-			if ok {
-				callName, ok := call.X.(*build.Ident)
-				if ok {
-					if callName.Name == "glob" {
-						for _, arg := range call.List {
-							strArg, ok := arg.(*build.StringExpr)
-							if ok && strings.Contains(strArg.Value, "/") {
-								return true
-							}
-						}
-					}
-				}
-			}
-		}
-		// TODO(b/120783741):
-		// This only handles a lists of files, and a single glob, there are other
-		// cases such as a glob + a list of files that it doesn't handle, but that's
-		// ok since, this is only meant as a caution to the user.
-	}
-
-	return false
-}
-
-// directoryOrAncestorHasSubdirectorySources checks for ts_libraries referencing sources in subdirectories.
-// It checks the current directory's BUILD if it exists, otherwise it checks the nearest
-// ancestor package.
-func directoryOrAncestorHasSubdirectorySources(ctx context.Context, g3root, workspaceRelativePath string, bld *build.File) (bool, error) {
-	if bld == nil {
-		// Make sure the next closest ancestor package doesn't reference sources in a subdirectory.
-		ancestor, err := FindBUILDFile(ctx, make(map[string]*build.File), g3root, filepath.Dir(workspaceRelativePath))
-		if _, ok := err.(*noAncestorBUILDError); ok {
-			// couldn't find an ancestor BUILD, so there aren't an subdirectory sources
-			return false, nil
-		} else if err != nil {
-			return false, err
-		} else if hasSubdirectorySources(ancestor) {
-			return true, nil
-		} else {
-			// there was an ancestor BUILD, but it didn't reference subdirectory sources
-			return false, nil
-		}
-	}
-
-	if hasSubdirectorySources(bld) {
-		return true, nil
-	}
-
-	return false, nil
-}
-
-func (upd *Updater) addSourcesToBUILD(ctx context.Context, path string, buildFilePath string, bld *build.File, srcs srcSet) (bool, error) {
-
-	platform.Infof("Updating sources")
-	if len(srcs) == 0 && len(allTSRules(bld)) == 0 {
-		// No TypeScript rules/sources, no need to update anything
-		return false, nil
-	}
-	updateSources(bld, srcs)
-
-	return upd.maybeWriteBUILD(ctx, buildFilePath, bld)
-}
-
-// 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,
-	g3root string, buildFilePath string, bld *build.File, reports []*arpb.DependencyReport) (bool, error) {
-	platform.Infof("Updating deps")
-	if err := updateDeps(bld, reports); err != nil {
-		return false, err
-	}
-
-	platform.Infof("Setting library rule kinds")
-	if err := setLibraryRuleKinds(ctx, buildFilePath, bld); err != nil {
-		return false, err
-	}
-	return upd.maybeWriteBUILD(ctx, buildFilePath, bld)
-}
-
-// IsTazeDisabledForDir checks if ts_auto_deps is disabled in the BUILD file in the dir,
-// or if no BUILD file exists, in the closest ancestor BUILD
-func IsTazeDisabledForDir(ctx context.Context, dir string) (bool, error) {
-	g3root, buildFilePath, workspaceRelativePath, err := getBUILDPath(ctx, dir)
-	if err != nil {
-		return false, err
-	}
-
-	bld, err := readBUILD(ctx, buildFilePath, workspaceRelativePath)
-	if err != nil {
-		platform.Infof("Error reading building file!")
-		return false, err
-	}
-
-	return isTazeDisabledInPackage(ctx, g3root, buildFilePath, workspaceRelativePath, bld)
-}
-
-// CantProgressAfterWriteError reports that ts_auto_deps was run in an environment
-// where it can't make writes to the file system (such as when ts_auto_deps is running
-// as a service for cider) and the writes it made need to be visible to bazel analyze,
-// so it can continue updating the BUILD file(s).  In such a case, the caller should
-// collect the writes using a custom UpdateFile function, and re-call ts_auto_deps after
-// applying the writes.
-type CantProgressAfterWriteError struct{}
-
-func (a *CantProgressAfterWriteError) Error() string {
-	return "running ts_auto_deps in a non-writable environment, can't continue until writes are applied"
-}
-
-// UpdateBUILDOptions bundles options for the UpdateBUILD function.
-type UpdateBUILDOptions struct {
-	// InNonWritableEnvironment boolean indicates to ts_auto_deps that the writes it makes
-	// won't be immediately visible to bazel analyze, so it cannot proceed normally.
-	// In this case, if it makes a write that needs to be visible to bazel analyze, it
-	// will return a CantProgressAfterWriteError, which indicates that the caller
-	// should apply the writes made to its UpdateFile function, and re-call UpdateBUILD
-	// after the writes have been applied.
-	InNonWritableEnvironment bool
-	// IsRoot indicates that the directory is a project's root directory, so a tsconfig
-	// rule should be created.
-	IsRoot bool
-}
-
-// LatencyReport contains timing measurements of the functions that are called
-// when running the presubmit on a package without any TypeScript (since we
-// return early to avoid the latency of RAS analyze).
-type LatencyReport struct {
-	GetBUILD, TazeDisabled, SubdirSrcs, AddSrcs time.Duration
-}
-
-// UpdateBUILD drives the main process of creating/updating the BUILD file
-// underneath path based on the available sources. Returns true if it modified
-// the BUILD file, false if the BUILD file was up to date already. bazelAnalyze
-// is used to run the underlying `bazel analyze` process.  Returns another
-// boolean that's true iff the package doesn't contain any TypeScript (source
-// files or BUILD rules).
-func (upd *Updater) UpdateBUILD(ctx context.Context, path string, options UpdateBUILDOptions) (bool, *LatencyReport, error) {
-	latencyReport := &LatencyReport{}
-
-	// asynchronously glob for TS sources in the package, since it can be slow on
-	// a network file system.
-	globChan := make(chan globResult)
-	go func() {
-		platform.Infof("Globbing TS sources in %s", path)
-		srcs, err := globSources(ctx, path, []string{"ts", "tsx"})
-		globChan <- globResult{srcs, err}
-	}()
-
-	start := time.Now()
-	g3root, buildFilePath, workspaceRelativePath, err := getBUILDPath(ctx, path)
-	if err != nil {
-		return false, nil, err
-	}
-
-	bld, err := readBUILD(ctx, buildFilePath, workspaceRelativePath)
-	if err != nil {
-		platform.Infof("Error reading building file!")
-		return false, nil, err
-	}
-	latencyReport.GetBUILD = time.Since(start)
-
-	start = time.Now()
-	ts_auto_depsDisabled, err := isTazeDisabledInPackage(ctx, g3root, buildFilePath, workspaceRelativePath, bld)
-	if err != nil {
-		return false, nil, err
-	}
-	latencyReport.TazeDisabled = time.Since(start)
-	if ts_auto_depsDisabled {
-		return false, nil, nil
-	}
-
-	start = time.Now()
-	hasSubdirSrcs, err := directoryOrAncestorHasSubdirectorySources(ctx, g3root, workspaceRelativePath, bld)
-	latencyReport.SubdirSrcs = time.Since(start)
-	if err != nil {
-		return false, nil, err
-	}
-	if hasSubdirSrcs {
-		return false, nil, &SubdirectorySourcesError{}
-	}
-
-	if bld == nil {
-		// The BUILD file didn't exist, so create a new, empty one.
-		bld = &build.File{Path: workspaceRelativePath, Type: build.TypeBuild}
-	}
-
-	start = time.Now()
-	globRes := <-globChan
-	if globRes.err != nil {
-		return false, nil, globRes.err
-	}
-	changed, err := upd.addSourcesToBUILD(ctx, path, buildFilePath, bld, globRes.srcs)
-	latencyReport.AddSrcs = time.Since(start)
-	if err != nil {
-		return false, nil, err
-	}
-	if options.InNonWritableEnvironment && changed {
-		return true, nil, &CantProgressAfterWriteError{}
-	}
-
-	rules := allTSRules(bld)
-	if len(rules) == 0 && !options.IsRoot {
-		// No TypeScript rules, no need to query for dependencies etc, so just exit early.
-		return changed, latencyReport, nil
-	}
-	rulesWithSrcs := []*build.Rule{}
-	for _, r := range rules {
-		srcs := r.Attr("srcs")
-		if srcs != nil {
-			if l, ok := srcs.(*build.ListExpr); ok && len(l.List) > 0 {
-				rulesWithSrcs = append(rulesWithSrcs, r)
-			}
-		}
-	}
-	platform.Infof("analyzing...")
-	reports, err := upd.runBazelAnalyze(buildFilePath, bld, rulesWithSrcs)
-	if err != nil {
-		return false, nil, err
-	}
-
-	changedAfterBazelAnalyze, err := upd.updateBUILDAfterBazelAnalyze(ctx, options.IsRoot, g3root, buildFilePath, bld, reports)
-	if err != nil {
-		return false, nil, err
-	}
-	changed = changed || changedAfterBazelAnalyze
-	if options.InNonWritableEnvironment && changed {
-		return true, nil, &CantProgressAfterWriteError{}
-	}
-
-	return changed, nil, nil
-}
-
-// buildHasDisableTaze checks if the BUILD file should be managed using ts_auto_deps.
-// Users can disable ts_auto_deps by adding a "disable_ts_auto_deps()" (or "dont_ts_auto_deps_me()") statement.
-func buildHasDisableTaze(bld *build.File) bool {
-	for _, stmt := range bld.Stmt {
-		if call, ok := stmt.(*build.CallExpr); ok {
-			if fnName, ok := call.X.(*build.Ident); ok && (fnName.Name == "disable_ts_auto_deps" || fnName.Name == "dont_ts_auto_deps_me") {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-// QueryBasedBazelAnalyze uses bazel query to analyze targets. It is available under a flag or
-// an environment variable on engineer's workstations.
-func QueryBasedBazelAnalyze(buildFilePath string, targets []string) ([]byte, []byte, error) {
-	root, err := workspace.Root(buildFilePath)
-	if err != nil {
-		return nil, nil, err
-	}
-	reports, err := analyze.New(analyze.NewQueryBasedTargetLoader(root, "bazel")).Analyze(context.Background(), buildFilePath, targets)
-	if err != nil {
-		return nil, nil, err
-	}
-	s, err := proto.Marshal(&arpb.AnalyzeResult{
-		DependencyReport: reports,
-	})
-	return s, nil, err
-}
-
-type ruleType int
-
-const (
-	ruleTypeAny ruleType = iota
-	ruleTypeRegular
-	ruleTypeTest
-	ruleTypeTestSupport
-)
-
-// isKind returns true if the rule has given kind.  It also accepts "ng_modules"
-// as "ts_library" kind.
-func isKind(r *build.Rule, kind string) bool {
-	acceptNgModule := kind == "ts_library"
-
-	return r.Kind() == kind || (acceptNgModule && r.Kind() == "ng_module")
-}
-
-func buildRules(bld *build.File, kind string) []*build.Rule {
-	// Find all rules, then filter by kind.
-	// This is nearly the same as just calling bld.Rules(kind), but allows to
-	// retrieve ng_module and ts_library intermixed, in the order in which they
-	// appear in the BUILD file. That allows ts_auto_deps to consistently always pick the
-	// last build rule in the file in case multiple match, regardless of kind.
-	allRules := bld.Rules("")
-	var res []*build.Rule
-	for _, r := range allRules {
-		if isKind(r, kind) {
-			res = append(res, r)
-		}
-	}
-	return res
-}
-
-// hasDependency returns whether a build rule contains the specified dependency.
-func hasDependency(bld *build.File, r *build.Rule, dep string) bool {
-	pkg := filepath.Dir(bld.Path)
-	oldDeps := r.Attr("deps")
-	if edit.ListFind(oldDeps, dep, pkg) != nil {
-		return true
-	}
-	runtimeDeps := r.Attr("runtime_deps")
-	return edit.ListFind(runtimeDeps, dep, pkg) != nil
-}
-
-// addDep adds a dependency to the specified build rule
-func addDep(bld *build.File, r *build.Rule, dep string) {
-	pkg := filepath.Dir(bld.Path)
-	dep = edit.ShortenLabel(dep, pkg)
-	if dep[0] != '/' && dep[0] != ':' {
-		dep = ":" + dep // ShortenLabel doesn't add the ':'
-	}
-	edit.AddValueToListAttribute(r, "deps", pkg, &build.StringExpr{Value: dep}, nil)
-}
-
-// AbsoluteBazelTarget converts a ruleName to an absolute target string (//foo/bar:bar).
-// It interprets ruleName relative to the given build file's package. It
-// supports plain names, names starting with colons, absolute paths, and
-// absolute paths with shorthand target syntax (i.e. "bar", ":bar", "//foo/bar",
-// "//foo/bar:bar").
-func AbsoluteBazelTarget(bld *build.File, ruleName string) string {
-	if strings.HasPrefix(ruleName, "//") {
-		// already absolute
-		if colonIdx := strings.LastIndex(ruleName, ":"); colonIdx == -1 {
-			// expand shorthand syntax
-			return ruleName + ":" + ruleName[strings.LastIndex(ruleName, "/")+1:]
-		}
-		return ruleName
-	}
-	pkg := platform.Normalize(filepath.Dir(bld.Path))
-	return fmt.Sprintf("//%s:%s", pkg, strings.TrimPrefix(ruleName, ":"))
-}
-
-// Finds all ts_library and ts_declaration targets in the given BUILD file.
-func allTSRules(bld *build.File) []*build.Rule {
-	var res []*build.Rule
-	res = append(res, buildRules(bld, "ts_library")...)
-	res = append(res, buildRules(bld, "ts_declaration")...)
-	return res
-}
-
-// removeSourcesUsed removes sources used by rules of kind ruleKind in attribute
-// attrName from the given set of sources.
-func removeSourcesUsed(bld *build.File, ruleKind, attrName string, srcs srcSet) {
-	for _, rule := range buildRules(bld, ruleKind) {
-		for s := range srcs {
-			pkg := filepath.Dir(bld.Path)
-			// Handles ":foo.ts" references, and concatenated lists [foo.ts] + [bar.ts]
-			// TODO(martinprobst): What to do about sources that don't seem to exist?
-			if edit.ListFind(rule.Attr(attrName), s, pkg) != nil {
-				delete(srcs, s)
-			}
-		}
-	}
-}
-
-const (
-	tsSkylarkLabel = "@npm_bazel_typescript//:index.bzl"
-	ngSkylarkLabel = "@angular//:index.bzl"
-)
-
-func removeUnusedLoad(bld *build.File, kind string) {
-	if len(bld.Rules(kind)) > 0 {
-		return // kind is still used somewhere.
-	}
-	var stmt []build.Expr
-	for _, s := range bld.Stmt {
-		load, ok := s.(*build.LoadStmt)
-		if !ok {
-			stmt = append(stmt, s)
-			continue
-		}
-		if len(load.To) == 0 {
-			// a load statement without actually loaded symbols, skip
-			continue
-		}
-
-		var from, to []*build.Ident
-		for i, ca := range load.To {
-			if ca.Name != kind {
-				from = append(from, load.From[i])
-				to = append(to, ca)
-			}
-		}
-		load.From = from
-		load.To = to
-		if len(to) > 0 {
-			stmt = append(stmt, load)
-			continue
-		}
-	}
-	bld.Stmt = stmt
-}
-
-// setLibraryRuleKinds sets the kinds for recognized library rules. That is, it
-// determines if a rule should be an ng_module, and sets the
-// rule kind if so. It also takes care of having the appropriate load calls.
-func setLibraryRuleKinds(ctx context.Context, buildFilePath string, bld *build.File) error {
-	hasNgModule := false
-	changed := false
-	for _, r := range buildRules(bld, "ts_library") {
-		shouldBeNgModule := false
-		isNgModule := r.Call.X.(*build.Ident).Name == "ng_module"
-		if hasAngularDependency(r) {
-			shouldBeNgModule = true
-			hasNgModule = true
-		}
-		if isNgModule && !shouldBeNgModule {
-			platform.Infof("Changing rule %s to ts_library()", r.AttrString("name"))
-			r.Call.X.(*build.Ident).Name = "ts_library"
-			r.DelAttr("assets")
-			changed = true
-		} else if !isNgModule && shouldBeNgModule {
-			platform.Infof("Changing rule %s to ng_module()", r.AttrString("name"))
-			r.Call.X.(*build.Ident).Name = "ng_module"
-			changed = true
-		}
-	}
-	if changed {
-		bld.Stmt = edit.InsertLoad(bld.Stmt, ngSkylarkLabel,
-			[]string{"ng_module"}, []string{"ng_module"})
-		bld.Stmt = edit.InsertLoad(bld.Stmt, tsSkylarkLabel,
-			[]string{"ts_library"}, []string{"ts_library"})
-		removeUnusedLoad(bld, "ts_library")
-		removeUnusedLoad(bld, "ng_module")
-	}
-	if !hasNgModule {
-		return nil
-	}
-	return updateWebAssets(ctx, buildFilePath, bld)
-}
-
-// hasAngularDependency returns true if the given rule depends on a Angular
-// build rule.
-func hasAngularDependency(r *build.Rule) bool {
-	e := r.Attr("deps")
-	for _, li := range edit.AllLists(e) {
-		for _, elem := range li.List {
-			str, ok := elem.(*build.StringExpr)
-			if ok && strings.HasPrefix(str.Value, "//third_party/javascript/angular2") {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-// updateWebAssets finds web assets in the package of the BUILD file and adds
-// them to the "assets" attribute of the ng_module rules.
-func updateWebAssets(ctx context.Context, buildFilePath string, bld *build.File) error {
-	// TODO(martinprobst): should this be merged with updateSources above? Difference is that
-	// creates new rules, this just distributes assets across them.
-	// This must use buildFilePath, the absolute path to the directory, as our cwd
-	// might not be the workspace root.
-	absolutePkgPath := filepath.Dir(buildFilePath)
-	assetFiles, err := globSources(ctx, absolutePkgPath, []string{"html", "css"})
-	if err != nil {
-		return err
-	}
-	platform.Infof("Found asset files in %s: %v", absolutePkgPath, assetFiles)
-
-	pkg := filepath.Dir(bld.Path)
-	for _, r := range bld.Rules("ng_module") {
-		srcs := r.Attr("assets")
-		if call, ok := srcs.(*build.CallExpr); ok && call.X.(*build.Ident).Name == "glob" {
-			// Remove any glob calls, ts_auto_deps uses explicit source lists.
-			r.DelAttr("assets")
-		}
-
-		for _, s := range r.AttrStrings("assets") {
-			if strings.HasPrefix(s, ":") || strings.HasPrefix(s, "//") {
-				continue // keep rule references
-			}
-			if _, ok := assetFiles[s]; !ok {
-				edit.ListAttributeDelete(r, "assets", s, pkg)
-			}
-		}
-	}
-
-	removeSourcesUsed(bld, "ng_module", "assets", assetFiles)
-	if len(assetFiles) == 0 {
-		return nil
-	}
-
-	// Add to the last rule, to match behaviour with *.ts sources.
-	lastModule := getLastRule(bld, "ng_module", ruleTypeRegular)
-	if lastModule == nil {
-		// Fall back to using any ng_module
-		lastModule = getLastRule(bld, "ng_module", ruleTypeAny)
-	}
-	if lastModule == nil {
-		// Should not happen by preconditions of this function.
-		return fmt.Errorf("no ng_module rules in BUILD?")
-	}
-
-	for newAsset := range assetFiles {
-		val := &build.StringExpr{Value: newAsset}
-		edit.AddValueToListAttribute(lastModule, "assets", pkg, val, nil)
-	}
-	return nil
-}
-
-// getOrCreateRule returns or creates a rule of the given kind, with testonly = 1 or 0 depending on
-// rt. If there's no such rule, it creates a new rule with the given ruleName.
-// If there is more than one rule matching, it returns the *last* rule.
-func getOrCreateRule(bld *build.File, ruleName, ruleKind string, rt ruleType) *build.Rule {
-	if r := getLastRule(bld, ruleKind, rt); r != nil {
-		return r
-	}
-
-	// TODO(calebegg): Switch this to "_test" but still support "_tests"
-	if rt == ruleTypeTest {
-		ruleName += "_tests"
-	}
-
-	loadArgs := []string{ruleKind}
-	bld.Stmt = edit.InsertLoad(bld.Stmt, tsSkylarkLabel, loadArgs, loadArgs)
-
-	r := &build.Rule{&build.CallExpr{X: &build.Ident{Name: ruleKind}}, ""}
-	// Rename to *_ts if there's a name collision. This leaves open a collision with another rule
-	// called _ts, but that failure mode is unlikely to happen accidentally.
-	if edit.FindRuleByName(bld, ruleName) != nil {
-		ruleName = ruleName + "_ts"
-	} else if filepath.Base(filepath.Dir(bld.Path)) == ruleName {
-		// The various *_ajd macros do not have a "name" attribute, but implicitly use the package name.
-		// Make sure not to use the package name if there is a *_ajd rule.
-		for _, r := range bld.Rules("") {
-			if r.Name() == "" && strings.HasSuffix(r.Kind(), "_ajd") {
-				ruleName = ruleName + "_ts"
-				break
-			}
-		}
-	}
-	r.SetAttr("name", &build.StringExpr{Value: ruleName})
-	if rt == ruleTypeTest || rt == ruleTypeTestSupport {
-		r.SetAttr("testonly", &build.Ident{Name: "True"})
-	}
-	bld.Stmt = append(bld.Stmt, r.Call)
-	return r
-}
-
-// ruleMatches return whether a rule matches the specified kind and rt value.
-func ruleMatches(bld *build.File, r *build.Rule, kind string, rt ruleType) bool {
-	if !isKind(r, kind) {
-		return false
-	}
-	inTestingDir := determineRuleType(bld.Path, "somefile.ts") == ruleTypeTestSupport
-	hasTestsName := strings.HasSuffix(r.Name(), "_tests")
-	// Accept the rule if it matches the testonly attribute.
-	if rt == ruleTypeAny {
-		return true
-	}
-	if attrTruthy(r, "testonly") {
-		if inTestingDir && ((hasTestsName && rt == ruleTypeTest) || (!hasTestsName && rt == ruleTypeTestSupport)) {
-			return true
-		}
-		if !inTestingDir && rt == ruleTypeTest {
-			return true
-		}
-	}
-	return rt == ruleTypeRegular && !attrTruthy(r, "testonly")
-}
-
-// targetRegisteredInRule returns whether a target has been registered in a rule that
-// matches a specified ruleKind and ruleType in current build file
-func targetRegisteredInRule(bld *build.File, ruleKind string, rt ruleType, target string) bool {
-	for _, r := range bld.Rules("") {
-		if ruleMatches(bld, r, ruleKind, rt) && hasDependency(bld, r, target) {
-			return true
-		}
-	}
-	return false
-}
-
-// getRule returns the last rule in bld that has the given ruleKind and matches
-// the specified rt value.
-func getLastRule(bld *build.File, ruleKind string, rt ruleType) *build.Rule {
-	rules := getRules(bld, ruleKind, rt)
-
-	if len(rules) == 0 {
-		return nil
-	}
-
-	return rules[len(rules)-1]
-}
-
-// getRules returns all the rules in bld that have the given ruleKind and
-// matches the specified rt value.
-func getRules(bld *build.File, ruleKind string, rt ruleType) []*build.Rule {
-	var rules []*build.Rule
-	for _, r := range bld.Rules("") {
-		if ruleMatches(bld, r, ruleKind, rt) {
-			rules = append(rules, r)
-		}
-	}
-
-	return rules
-}
-
-// FilterPaths filters the given paths, returning the deduplicated set of
-// folders that contain TypeScript sources (.ts and .tsx) or BUILD files.
-func FilterPaths(paths []string) []string {
-	fileSet := make(map[string]bool)
-	for _, p := range paths {
-		if !strings.HasSuffix(p, ".ts") && !strings.HasSuffix(p, ".tsx") && filepath.Base(p) != "BUILD" {
-			continue
-		}
-		fileSet[filepath.Dir(p)] = true
-	}
-	var newPaths []string
-	for k := range fileSet {
-		newPaths = append(newPaths, platform.Normalize(k))
-	}
-	return newPaths
-}
-
-// ResolvePackages resolves package paths, i.e. paths starting with '//',
-// against the workspace root folder closest to the current working directory.
-// It updates paths in place.
-// It returns an error if it cannot find a workspace root or working directory.
-func ResolvePackages(paths []string) error {
-	for i, p := range paths {
-		if strings.HasPrefix(p, "//") {
-			wd, err := os.Getwd()
-			if err != nil {
-				return fmt.Errorf("failed to get working directory: %v", err)
-			}
-			g3root, err := workspace.Root(wd)
-			if err != nil {
-				return fmt.Errorf("failed to find workspace root under %q: %v", wd, err)
-			}
-			paths[i] = filepath.Join(g3root, p)
-		}
-	}
-	return nil
-}
-
-type noAncestorBUILDError struct{}
-
-func (nabe *noAncestorBUILDError) Error() string {
-	return "no ancestor BUILD file found"
-}
-
-// FindBUILDFile searches for the closest parent BUILD file above pkg. It
-// returns the parsed BUILD file, or an error if none can be found.
-func FindBUILDFile(ctx context.Context, pkgToBUILD map[string]*build.File,
-	workspaceRoot string, packagePath string) (*build.File, error) {
-	if packagePath == "." || packagePath == "/" {
-		return nil, &noAncestorBUILDError{}
-	}
-	if bld, ok := pkgToBUILD[packagePath]; ok {
-		return bld, nil
-	}
-	buildPath := filepath.Join(workspaceRoot, packagePath, "BUILD")
-	bld, err := readBUILD(ctx, buildPath, filepath.Join(packagePath, "BUILD"))
-	if err != nil {
-		return nil, err
-	} else if bld == nil {
-		// Recursively search parent package and cache its location below if found.
-		bld, err = FindBUILDFile(ctx, pkgToBUILD, workspaceRoot, filepath.Dir(packagePath))
-	}
-	if err == nil {
-		// NB: The cache key is packagePath ('foo/bar/baz'), even if build file was
-		// found at a higher location ('foo/BUILD'). This avoids re-testing for file
-		// existence.
-		pkgToBUILD[packagePath] = bld
-	}
-	return bld, err
-}
-
-// Paths gets the list of paths for the current execution of ts_auto_deps.
-func Paths(isRoot bool, files bool, recursive bool) ([]string, error) {
-	paths := flag.Args()
-	if len(paths) == 0 {
-		wd, err := os.Getwd()
-		if err != nil {
-			return nil, fmt.Errorf("failed to get working directory: %v", err)
-		}
-		paths = []string{wd}
-	}
-
-	if len(paths) > 1 && isRoot {
-		return nil, fmt.Errorf("can only take exactly one path with -root")
-	}
-
-	if files {
-		paths = FilterPaths(paths)
-		if len(paths) == 0 {
-			return nil, fmt.Errorf("WARNING: found no TypeScript files in %s", paths)
-		}
-	}
-
-	if err := ResolvePackages(paths); err != nil {
-		return nil, fmt.Errorf("failed to resolve packages: %s", err)
-	}
-
-	if recursive {
-		var lock sync.Mutex // guards allPaths
-		var allPaths []string
-		for _, p := range paths {
-			err := platform.Walk(p, func(path string, info os.FileMode) error {
-				if info.IsDir() {
-					lock.Lock()
-					allPaths = append(allPaths, path)
-					lock.Unlock()
-				}
-				return nil
-			})
-			if err != nil {
-				return nil, fmt.Errorf("ts_auto_deps -recursive failed: %s", err)
-			}
-		}
-		sort.Sort(byLengthInverted(allPaths))
-		paths = allPaths
-	}
-
-	return paths, nil
-}
-
-// Execute runs ts_auto_deps on paths using host.
-func Execute(host *Updater, paths []string, isRoot, recursive bool) error {
-	ctx := context.Background()
-	for i, p := range paths {
-		isLastAndRoot := isRoot && i == len(paths)-1
-		changed, _, err := host.UpdateBUILD(ctx, p, UpdateBUILDOptions{InNonWritableEnvironment: false, IsRoot: isLastAndRoot})
-		if err != nil {
-			if recursive {
-				return fmt.Errorf("ts_auto_deps failed on %s/BUILD: %s", p, err)
-			}
-			return fmt.Errorf("ts_auto_deps failed: %s", err)
-		}
-		if changed {
-			if filepath.Base(p) == "BUILD" {
-				fmt.Printf("Wrote %s\n", p)
-			} else {
-				fmt.Printf("Wrote %s\n", filepath.Join(p, "BUILD"))
-			}
-		}
-	}
-	host.RegisterTestRules(ctx, paths...)
-	return nil
-}
-
-// allPaths walks the file system and returns a list of all directories under
-// all paths.
-func allPaths(paths []string) ([]string, error) {
-	var allPaths []string
-	for _, p := range paths {
-		err := filepath.Walk(p, func(path string, info os.FileInfo, err error) error {
-			if err == nil && info.IsDir() {
-				allPaths = append(allPaths, path)
-			}
-			return err
-		})
-		if err != nil {
-			return nil, err
-		}
-	}
-	sort.Sort(byLengthInverted(allPaths))
-	return allPaths, nil
-}
-
-type byLengthInverted []string
-
-func (s byLengthInverted) Len() int           { return len(s) }
-func (s byLengthInverted) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s byLengthInverted) Less(i, j int) bool { return len(s[i]) > len(s[j]) }
diff --git a/ts_auto_deps/updater/updater_test.go b/ts_auto_deps/updater/updater_test.go
deleted file mode 100644
index 613b99f..0000000
--- a/ts_auto_deps/updater/updater_test.go
+++ /dev/null
@@ -1,563 +0,0 @@
-package updater
-
-import (
-	"context"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"testing"
-
-	"github.com/bazelbuild/buildtools/build"
-	"github.com/golang/protobuf/proto"
-
-	arpb "github.com/bazelbuild/rules_typescript/ts_auto_deps/proto"
-)
-
-var (
-	testTmpDir = os.Getenv("TEST_TMPDIR")
-)
-
-func mktmp(fn string, content []byte) (string, error) {
-	p := fn
-	if !filepath.IsAbs(p) {
-		p = filepath.Join(testTmpDir, fn)
-	}
-	if err := os.MkdirAll(filepath.Dir(p), 0777); err != nil {
-		return "", err
-	}
-	return p, ioutil.WriteFile(p, content, 0666)
-}
-
-func TestReadBuild(t *testing.T) {
-	p, err := mktmp("google3/foo/bar/BUILD", []byte(`
-ts_library(name = 'a', srcs = ['b.ts'])
-`))
-	if err != nil {
-		t.Fatal(err)
-	}
-	bld, err := readBUILD(context.Background(), p, "foo/bar/BUILD")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if bld.Path != "foo/bar/BUILD" {
-		t.Errorf("bld.Path: got %s, expected %s", bld.Path, "foo/bar/BUILD")
-	}
-}
-
-func TestGlobSources(t *testing.T) {
-	for _, f := range []string{"a.ts", "a/b.ts", "c.tsx", "whatever", "foo.cpp", "d.d.ts", "._e.ts"} {
-		if _, err := mktmp(f, []byte("// content")); err != nil {
-			t.Fatal(err)
-		}
-	}
-	if err := os.Symlink("../bazel-bin/symlink.d.ts", filepath.Join(testTmpDir, "symlink.d.ts")); err != nil {
-		t.Fatal(err)
-	}
-	if err := os.Symlink("whatever", filepath.Join(testTmpDir, "whatever.d.ts")); err != nil {
-		t.Fatal(err)
-	}
-	srcs, err := globSources(context.Background(), testTmpDir, []string{"ts", "tsx"})
-	if err != nil {
-		t.Fatal(err)
-	}
-	expected := srcSet(map[string]bool{
-		"a.ts":          true,
-		"c.tsx":         true,
-		"d.d.ts":        true,
-		"whatever.d.ts": true,
-	})
-	if !reflect.DeepEqual(srcs, expected) {
-		t.Errorf("globSources: got %v, want %v", srcs, expected)
-	}
-}
-
-func TestDetermineRuleType(t *testing.T) {
-	tests := []struct {
-		path   string
-		source string
-		rt     ruleType
-	}{
-		{"java/com/google/myapp/BUILD", "foo.ts", ruleTypeRegular},
-		{"java/com/google/myapp/BUILD", "foo_test.ts", ruleTypeTest},
-		{"java/com/google/myapp/BUILD", "foo_test.tsx", ruleTypeTest},
-
-		{"java/com/google/testing/mytesttool/BUILD", "foo.ts", ruleTypeRegular},
-		{"testing/mytesttool/BUILD", "foo.ts", ruleTypeRegular},
-		{"testing/mytesttool/BUILD", "foo_test.ts", ruleTypeTest},
-		{"testing/mytesttool/BUILD", "foo_test.ts", ruleTypeTest},
-	}
-	for _, tst := range tests {
-		rt := determineRuleType(tst.path, tst.source)
-		if rt != tst.rt {
-			t.Errorf("determineRuleType(%q, %q): got %v, expected %v", tst.path, tst.source, rt, tst.rt)
-		}
-	}
-}
-
-func parseReport(t *testing.T, input string) *arpb.DependencyReport {
-	report := &arpb.DependencyReport{}
-	if err := proto.UnmarshalText(input, report); err != nil {
-		t.Error(err)
-	}
-	return report
-}
-
-func TestBazelAnalyzeError(t *testing.T) {
-	bld, err := build.ParseBuild("rules/BUILD", []byte(`
-ts_library(
-	name = "firstrule",
-	srcs = [],
-)
-ts_library(
-	name = "secondrule",
-	srcs = [],
-)
-	`))
-	if err != nil {
-		t.Fatal(err)
-	}
-	mockAnalyze := func(_ string, targets []string) ([]byte, []byte, error) {
-		data, err := proto.Marshal(&arpb.AnalyzeResult{
-			DependencyReport: []*arpb.DependencyReport{&arpb.DependencyReport{
-				Rule: proto.String("//rules:firstrule"),
-			}},
-		})
-		return data, []byte(`Here's the actual error`), err
-	}
-	upd := &Updater{}
-	upd.bazelAnalyze = mockAnalyze
-	report, err := upd.runBazelAnalyze("firstrule/BUILD", bld, bld.Rules("ts_library"))
-	if err == nil {
-		t.Fatalf("expected an error, got a report: %v", report)
-	}
-	expected := `parsing reports failed (1 reports for [//rules:firstrule //rules:secondrule]):
-Here's the actual error`
-	if err.Error() != expected {
-		t.Errorf("runBazelAnalyze: got %q, expected %q", err.Error(), expected)
-	}
-}
-
-func TestUpdateDeps(t *testing.T) {
-	report := parseReport(t, `
-			rule: "//foo:bar"
-			unnecessary_dependency: "//unnecessary_dep"
-			missing_dependency_group: {
-				dependency: "//missing_dep"
-			}
-			missing_source_file: "missing_file.ts"`)
-
-	tests := []struct {
-		name    string
-		before  string
-		after   string
-		changed bool
-	}{
-		{
-			"Add missing dependency",
-			`ts_library(
-					name = "bar",
-					deps = [],
-			)`,
-			`ts_library(
-					name = "bar",
-					deps = ["//missing_dep"],
-			)`,
-			true,
-		},
-		{
-			"Remove + Add dependency",
-			`ts_library(
-					name = "bar",
-					deps = ["//unnecessary_dep"],
-			)`,
-			`ts_library(
-					name = "bar",
-					deps = ["//missing_dep"],
-			)`,
-			true,
-		},
-		{
-			"Remove nonexistent dep (e.g. due to macro)",
-			`ts_library(
-					name = "bar",
-					deps = ["//missing_dep"],
-			)`,
-			`ts_library(
-					name = "bar",
-					deps = ["//missing_dep"],
-			)`,
-			false, // Unchanged!
-		},
-		{
-			"Remove nonexistent src",
-			`ts_library(
-					name = "bar",
-					srcs = ["hello.ts"],
-					deps = ["//missing_dep"],
-			)`,
-			`ts_library(
-					name = "bar",
-					srcs = ["hello.ts"],
-					deps = ["//missing_dep"],
-			)`,
-			false, // Unchanged!
-		},
-	}
-	for _, tst := range tests {
-		bld, err := build.ParseBuild("foo/BUILD", []byte(tst.before))
-		if err != nil {
-			t.Errorf("parse %s failed: %s in %s", tst.name, err, tst.before)
-		}
-		bldAft, err := build.ParseBuild("foo/BUILD", []byte(tst.after))
-		if err != nil {
-			t.Errorf("parse %s after failed: %s", tst.name, err)
-		}
-		if err := updateDeps(bld, []*arpb.DependencyReport{report}); err != nil {
-			t.Errorf("update %s failed: %s", tst.name, err)
-		}
-		updated := string(build.Format(bld))
-		after := string(build.Format(bldAft))
-		if updated != after {
-			t.Errorf("update(%s), got:\n%s\n\nexpected:\n%s", tst.name, updated, after)
-		}
-	}
-}
-
-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)
-	}
-
-	expectedErr := "'// from ...'' comment, or the target BUILD files are incorrect?"
-
-	err = updateDeps(bld, []*arpb.DependencyReport{report})
-	if !strings.Contains(err.Error(), expectedErr) {
-		t.Errorf("returned error %s: expected it to contain %s", err, expectedErr)
-	}
-}
-
-func TestDottedCall(t *testing.T) {
-	// Repro for a crash, b/35389044
-	buildText := `foo.bar("baz")`
-	bld, err := build.ParseBuild("test", []byte(buildText))
-	if err != nil {
-		t.Error(err)
-	}
-	removeUnusedLoad(bld, "ignored")
-}
-
-func TestFilterPaths(t *testing.T) {
-	tests := []struct {
-		in       []string
-		expected []string
-	}{
-		{[]string{"foo/bar.txt", "foo/baz.ts"}, []string{"foo"}},
-		{[]string{"bam.ts"}, []string{"."}},
-		{[]string{"foo/BUILD"}, []string{"foo"}},
-		{[]string{"r/foo.tsx"}, []string{"r"}},
-		{[]string{"../../x.ts"}, []string{"../.."}},
-		{[]string{"a.txt", "foo/b.txt"}, []string(nil)},
-	}
-	for _, tst := range tests {
-		res := FilterPaths(tst.in)
-		if !reflect.DeepEqual(res, tst.expected) {
-			t.Errorf("FilterPaths(%v): got %v, expected %v", tst.in, res, tst.expected)
-		}
-	}
-}
-
-func TestAddDep(t *testing.T) {
-	tests := []struct {
-		buildFile string
-		newDep    string
-		expected  string
-	}{
-		{`ts_library(name = "lib", deps = ["//a", "//b", "//c"])`,
-			"//b",
-			`ts_library(name = "lib", deps = ["//a", "//b", "//c"])`},
-		{`ts_library(name = "lib", deps = ["//a", "//b", "//c"])`,
-			"//d",
-			`ts_library(name = "lib", deps = ["//a", "//b", "//c", "//d"])`},
-		{`ts_library(name = "lib", deps = ["//a", ":b", "//c"])`,
-			":b",
-			`ts_library(name = "lib", deps = ["//a", ":b", "//c"])`},
-		{`ts_library(name = "lib", deps = ["//a", ":b", "//c"])`,
-			"//buildloc:b",
-			`ts_library(name = "lib", deps = ["//a", ":b", "//c"])`},
-		{`ts_library(name = "lib", deps = ["//a", "//buildloc:b", "//c"])`,
-			":b",
-			`ts_library(name = "lib", deps = ["//a", "//buildloc:b", "//c"])`},
-		{`ts_library(name = "lib", deps = ["//a", "//other:b", "//c"])`,
-			":b",
-			`ts_library(name = "lib", deps = [":b", "//a", "//other:b", "//c"])`},
-		{`ts_library(name = "lib", deps = ["//a", "//other:b", "//c"])`,
-			"//a:a",
-			`ts_library(name = "lib", deps = ["//a", "//other:b", "//c"])`},
-	}
-	for _, tst := range tests {
-		bld, err := build.ParseBuild("buildloc/BUILD", []byte(tst.buildFile))
-		if err != nil {
-			t.Fatalf("parse failure: %s - %v", tst.buildFile, err)
-		}
-		addDep(bld, bld.Rules("ts_library")[0], tst.newDep)
-		newContent := string(build.Format(bld))
-		expectedBld, err := build.ParseBuild("buildloc/BUILD", []byte(tst.expected))
-		if err != nil {
-			t.Fatalf("parse failure: %s - %v", tst.expected, err)
-		}
-		expected := string(build.Format(expectedBld))
-		if newContent != expected {
-			t.Errorf("addDep(%s, %s): got %v, expected %v", tst.buildFile, tst.newDep, newContent, tst.expected)
-		}
-	}
-}
-
-func TestRemoveSourcesUsed(t *testing.T) {
-	tests := []struct {
-		name         string
-		buildFile    string
-		ruleKind     string
-		attrName     string
-		srcs         srcSet
-		expectedSrcs srcSet
-	}{
-		{
-			name:         "RemovesSources",
-			buildFile:    `ts_library(name = "lib", srcs = ["foo.ts", "bar.ts"])`,
-			ruleKind:     "ts_library",
-			attrName:     "srcs",
-			srcs:         map[string]bool{"foo.ts": true},
-			expectedSrcs: map[string]bool{},
-		},
-		{
-			name:         "WrongRuleKind",
-			buildFile:    `ts_library(name = "lib", srcs = ["foo.ts", "bar.ts"])`,
-			ruleKind:     "ng_module",
-			attrName:     "srcs",
-			srcs:         map[string]bool{"foo.ts": true},
-			expectedSrcs: map[string]bool{"foo.ts": true},
-		},
-		{
-			name:         "WrongAttrName",
-			buildFile:    `ts_library(name = "lib", srcs = ["foo.ts", "bar.ts"])`,
-			ruleKind:     "ts_library",
-			attrName:     "deps",
-			srcs:         map[string]bool{"foo.ts": true},
-			expectedSrcs: map[string]bool{"foo.ts": true},
-		},
-		{
-			name: "MultipleRules",
-			buildFile: `ts_library(name = "lib", srcs = ["foo.ts"])
-			ts_library(name = "lib2", srcs = ["bar.ts"])`,
-			ruleKind:     "ts_library",
-			attrName:     "srcs",
-			srcs:         map[string]bool{"foo.ts": true, "bar.ts": true},
-			expectedSrcs: map[string]bool{},
-		},
-		{
-			name:         "ConcatenatedLists",
-			buildFile:    `ts_library(name = "lib", srcs = ["foo.ts"] + ["bar.ts"])`,
-			ruleKind:     "ts_library",
-			attrName:     "srcs",
-			srcs:         map[string]bool{"foo.ts": true, "bar.ts": true},
-			expectedSrcs: map[string]bool{},
-		},
-		{
-			name:         "ColonReferences",
-			buildFile:    `ts_library(name = "lib", srcs = [":foo.ts", "bar.ts"])`,
-			ruleKind:     "ts_library",
-			attrName:     "srcs",
-			srcs:         map[string]bool{"foo.ts": true},
-			expectedSrcs: map[string]bool{},
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			bld, err := build.ParseBuild("foo/bar/BUILD",
-				[]byte(test.buildFile))
-			if err != nil {
-				t.Fatalf("parse failure: %v", err)
-			}
-
-			removeSourcesUsed(bld, test.ruleKind, test.attrName, test.srcs)
-			if !reflect.DeepEqual(test.srcs, test.expectedSrcs) {
-				t.Errorf("expected removeSourcesUsed() = %v, expected %v", test.srcs, test.expectedSrcs)
-			}
-		})
-	}
-}
-
-func TestUpdateWebAssets(t *testing.T) {
-	ctx := context.Background()
-	bld, err := build.ParseBuild("foo/bar/BUILD",
-		[]byte(`ng_module(name = "m", assets = [":rule", "gone.html"])`))
-	if err != nil {
-		t.Fatalf("parse failure: %v", err)
-	}
-	testHTML, err := mktmp("google3/foo/bar/test.html", []byte(`<p>test</p>`))
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer func() {
-		if err := os.Remove(testHTML); err != nil {
-			t.Error(err)
-		}
-	}()
-	testCSS, err := mktmp("google3/foo/bar/test.css", []byte(`.test {}`))
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer func() {
-		if err := os.Remove(testCSS); err != nil {
-			t.Error(err)
-		}
-	}()
-	absoluteBuildPath := filepath.Join(filepath.Dir(testCSS), "BUILD")
-	if err := updateWebAssets(ctx, absoluteBuildPath, bld); err != nil {
-		t.Fatal(err)
-	}
-	data := string(build.Format(bld))
-	expected := `ng_module(
-    name = "m",
-    assets = [
-        ":rule",
-        "test.css",
-        "test.html",
-    ],
-)
-`
-	if data != expected {
-		t.Errorf("build file mismatch, got %s, expected %s", data, expected)
-	}
-}
-
-func TestWebAssetReferredByColon(t *testing.T) {
-	ctx := context.Background()
-	bld, err := build.ParseBuild("foo/bar/BUILD",
-		[]byte(`ng_module(name = "m", assets = [":colon.html"])`))
-	if err != nil {
-		t.Fatalf("parse failure: %v", err)
-	}
-	colon, err := mktmp("google3/foo/bar/colon.html", []byte(`<p>test</p>`))
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer func() {
-		if err := os.Remove(colon); err != nil {
-			t.Error(err)
-		}
-	}()
-	absolutBuildPath := filepath.Join(filepath.Dir(colon), "BUILD")
-	if err := updateWebAssets(ctx, absolutBuildPath, bld); err != nil {
-		t.Error(err)
-	}
-	data := string(build.Format(bld))
-	expected := `ng_module(
-    name = "m",
-    assets = [":colon.html"],
-)
-`
-	if data != expected {
-		t.Errorf("build file mismatch, got %s, expected %s", data, expected)
-	}
-}
-
-func TestAbsoluteBazelTarget(t *testing.T) {
-	bld := &build.File{Path: "foo/bar/BUILD", Type: build.TypeBuild}
-	tests := []struct{ target, expected string }{
-		{"//foo/bar:bar", "//foo/bar:bar"},
-		{":bar", "//foo/bar:bar"},
-		{"bar", "//foo/bar:bar"},
-		{"//foo/bar", "//foo/bar:bar"},
-	}
-	for _, tst := range tests {
-		abs := AbsoluteBazelTarget(bld, tst.target)
-		if abs != tst.expected {
-			t.Errorf("AbsoluteBazelTarget(%q): got %q, expected %q", tst.target, abs, tst.expected)
-		}
-	}
-}
-
-func TestFindBUILDFileCacheOnError(t *testing.T) {
-	ctx := context.Background()
-	cache := make(map[string]*build.File)
-	p, err := mktmp("google3/pkg/file", []byte(""))
-	if err != nil {
-		t.Fatal(err)
-	}
-	g3root := filepath.Dir(filepath.Dir(p))
-	if filepath.Base(g3root) != "google3" {
-		t.Errorf("g3root should be called google3, got %q", g3root)
-	}
-	// No BUILD file was created in the file system so FindBUILDFile should
-	// return an error.
-	if _, err = FindBUILDFile(ctx, cache, g3root, "pkg"); err == nil {
-		t.Fatalf("returned no error, expected some error to occur")
-	}
-	if _, ok := cache["pkg"]; ok {
-		t.Fatalf("cache contained BUILD file for package")
-	}
-}
-
-func TestHasSubdirectorySources(t *testing.T) {
-	tests := []struct {
-		name      string
-		buildFile string
-		expected  bool
-	}{
-		{
-			name:      "LocalSources",
-			buildFile: `ts_library(name = "lib", srcs = ["foo.ts", "bar.ts"])`,
-			expected:  false,
-		},
-		{
-			name:      "SubdirectorySources",
-			buildFile: `ts_library(name = "lib", srcs = ["subdir/foo.ts", "subdir/bar.ts"])`,
-			expected:  true,
-		},
-		{
-			name:      "LocalNgModuleSources",
-			buildFile: `ng_module(name = "lib", srcs = ["foo.ts", "bar.ts"])`,
-			expected:  false,
-		},
-		{
-			name:      "SubdirectoryNgModuleSources",
-			buildFile: `ng_module(name = "lib", srcs = ["subdir/foo.ts", "subdir/bar.ts"])`,
-			expected:  true,
-		},
-		{
-			name:      "LocalGlob",
-			buildFile: `ts_library(name = "lib", srcs = glob("*.ts"))`,
-			expected:  false,
-		},
-		{
-			name:      "SubdirectoryGlob",
-			buildFile: `ts_library(name = "lib", srcs = glob("**/*.ts"))`,
-			expected:  true,
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			bld, err := build.ParseBuild("foo/bar/BUILD",
-				[]byte(test.buildFile))
-			if err != nil {
-				t.Fatalf("parse failure: %v", err)
-			}
-
-			actual := hasSubdirectorySources(bld)
-			if actual != test.expected {
-				t.Errorf("got hasSubdirectorySouces() = %v, expected %v", actual, test.expected)
-			}
-		})
-	}
-}
diff --git a/ts_auto_deps/workspace/BUILD.bazel b/ts_auto_deps/workspace/BUILD.bazel
deleted file mode 100644
index 38f8123..0000000
--- a/ts_auto_deps/workspace/BUILD.bazel
+++ /dev/null
@@ -1,9 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["workspace.go"],
-    importpath = "github.com/bazelbuild/rules_typescript/ts_auto_deps/workspace",
-    visibility = ["//visibility:public"],
-    deps = ["@com_github_bazelbuild_buildtools//wspace:go_default_library"],
-)
diff --git a/ts_auto_deps/workspace/workspace.go b/ts_auto_deps/workspace/workspace.go
deleted file mode 100644
index c7f1ac2..0000000
--- a/ts_auto_deps/workspace/workspace.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package workspace
-
-import "github.com/bazelbuild/buildtools/wspace"
-
-// Root finds the closest directory containing a WORKSPACE file from p.
-func Root(p string) (string, error) {
-	return wspace.Find(p)
-}
-
-// Name returns the name of the workspace.
-func Name() string {
-	return "TODO"
-}
