build/toolbase: init

In an effort to better the developer/CI experience, I'm moving some of
our presubmit checks into a Go tool. This is a helper library that will
be used to interact with a Monogon workspace checkout from Go, both in
the new presubmit tool but also any other future tools that would like
to operate on source code.

Change-Id: Ie5f1b1d0153a1c853c241e167d2d3a469c636c94
Reviewed-on: https://review.monogon.dev/c/monogon/+/328
Reviewed-by: Mateusz Zalega <mateusz@monogon.tech>
diff --git a/build/toolbase/label_test.go b/build/toolbase/label_test.go
new file mode 100644
index 0000000..190c834
--- /dev/null
+++ b/build/toolbase/label_test.go
@@ -0,0 +1,59 @@
+package toolbase
+
+import (
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+)
+
+func TestBazelLabelParse(t *testing.T) {
+	for i, te := range []struct {
+		p string
+		t *BazelLabel
+	}{
+		{"//foo/bar", &BazelLabel{"dev_source_monogon", []string{"foo", "bar"}, "bar"}},
+		{"//foo/bar:baz", &BazelLabel{"dev_source_monogon", []string{"foo", "bar"}, "baz"}},
+		{"//:foo", &BazelLabel{"dev_source_monogon", nil, "foo"}},
+
+		{"@test//foo/bar", &BazelLabel{"test", []string{"foo", "bar"}, "bar"}},
+		{"@test//foo/bar:baz", &BazelLabel{"test", []string{"foo", "bar"}, "baz"}},
+		{"@test//:foo", &BazelLabel{"test", nil, "foo"}},
+
+		{"", nil},
+		{"//", nil},
+		{"//foo:bar/foo", nil},
+		{"//foo//bar/foo", nil},
+		{"/foo/bar/foo", nil},
+		{"foo/bar/foo", nil},
+		{"@//foo/bar/foo", nil},
+		{"@foo/bar//foo/bar/foo", nil},
+		{"@foo:bar//foo/bar/foo", nil},
+		{"foo//foo/bar/foo", nil},
+	} {
+		want := te.t
+		got := ParseBazelLabel(te.p)
+		if diff := cmp.Diff(want, got); diff != "" {
+			t.Errorf("case %d (%q): %s", i, te.p, diff)
+		}
+	}
+}
+
+func TestBazelLabelString(t *testing.T) {
+	for i, te := range []struct {
+		in   string
+		want string
+	}{
+		{"//foo/bar", "@dev_source_monogon//foo/bar:bar"},
+		{"//foo:bar", "@dev_source_monogon//foo:bar"},
+		{"@com_github_example//:run", "@com_github_example//:run"},
+	} {
+		l := ParseBazelLabel(te.in)
+		if l == nil {
+			t.Errorf("case %d: wanted %q, got nil", i, te.want)
+			continue
+		}
+		if want, got := te.want, l.String(); want != got {
+			t.Errorf("case %d: wanted %q, got %q", i, want, got)
+		}
+	}
+}