fix: gazelle panics when "# gazelle:ignore" doesn't have a value (#915)

* add panic case

* fix: return nil if invalid annotation is provided instead of panic

* fix after review

* Update gazelle/parser.go

Co-authored-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>

* Update gazelle/testdata/invalid_annotation/test.yaml

Co-authored-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>

Co-authored-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>
diff --git a/gazelle/parser.go b/gazelle/parser.go
index d287caf..6158d38 100644
--- a/gazelle/parser.go
+++ b/gazelle/parser.go
@@ -128,7 +128,10 @@
 	}
 
 	for _, res := range allRes {
-		annotations := annotationsFromComments(res.Comments)
+		annotations, err := annotationsFromComments(res.Comments)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse annotations: %w", err)
+		}
 
 		for _, m := range res.Modules {
 			// Check for ignored dependencies set via an annotation to the Python
@@ -195,17 +198,20 @@
 
 // asAnnotation returns an annotation object if the comment has the
 // annotationPrefix.
-func (c *comment) asAnnotation() *annotation {
+func (c *comment) asAnnotation() (*annotation, error) {
 	uncomment := strings.TrimLeft(string(*c), "# ")
 	if !strings.HasPrefix(uncomment, annotationPrefix) {
-		return nil
+		return nil, nil
 	}
 	withoutPrefix := strings.TrimPrefix(uncomment, annotationPrefix)
 	annotationParts := strings.SplitN(withoutPrefix, " ", 2)
+	if len(annotationParts) < 2 {
+		return nil, fmt.Errorf("`%s` requires a value", *c)
+	}
 	return &annotation{
 		kind:  annotationKind(annotationParts[0]),
 		value: annotationParts[1],
-	}
+	}, nil
 }
 
 // annotation represents a single Gazelle annotation parsed from a Python
@@ -224,10 +230,13 @@
 
 // annotationsFromComments returns all the annotations parsed out of the
 // comments of a Python module.
-func annotationsFromComments(comments []comment) *annotations {
+func annotationsFromComments(comments []comment) (*annotations, error) {
 	ignore := make(map[string]struct{})
 	for _, comment := range comments {
-		annotation := comment.asAnnotation()
+		annotation, err := comment.asAnnotation()
+		if err != nil {
+			return nil, err
+		}
 		if annotation != nil {
 			if annotation.kind == annotationKindIgnore {
 				modules := strings.Split(annotation.value, ",")
@@ -243,7 +252,7 @@
 	}
 	return &annotations{
 		ignore: ignore,
-	}
+	}, nil
 }
 
 // ignored returns true if the given module was ignored via the ignore
diff --git a/gazelle/testdata/invalid_annotation/BUILD.in b/gazelle/testdata/invalid_annotation/BUILD.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gazelle/testdata/invalid_annotation/BUILD.in
diff --git a/gazelle/testdata/invalid_annotation/BUILD.out b/gazelle/testdata/invalid_annotation/BUILD.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gazelle/testdata/invalid_annotation/BUILD.out
diff --git a/gazelle/testdata/invalid_annotation/README.md b/gazelle/testdata/invalid_annotation/README.md
new file mode 100644
index 0000000..b2544b5
--- /dev/null
+++ b/gazelle/testdata/invalid_annotation/README.md
@@ -0,0 +1,2 @@
+# Invalid  annotation
+This test case asserts that the parse step fails as expected due to invalid annotation format.
diff --git a/gazelle/testdata/invalid_annotation/WORKSPACE b/gazelle/testdata/invalid_annotation/WORKSPACE
new file mode 100644
index 0000000..faff6af
--- /dev/null
+++ b/gazelle/testdata/invalid_annotation/WORKSPACE
@@ -0,0 +1 @@
+# This is a Bazel workspace for the Gazelle test data.
diff --git a/gazelle/testdata/invalid_annotation/__init__.py b/gazelle/testdata/invalid_annotation/__init__.py
new file mode 100644
index 0000000..9968c4a
--- /dev/null
+++ b/gazelle/testdata/invalid_annotation/__init__.py
@@ -0,0 +1 @@
+# gazelle:ignore
diff --git a/gazelle/testdata/invalid_annotation/test.yaml b/gazelle/testdata/invalid_annotation/test.yaml
new file mode 100644
index 0000000..5e6170b
--- /dev/null
+++ b/gazelle/testdata/invalid_annotation/test.yaml
@@ -0,0 +1,5 @@
+---
+expect:
+  exit_code: 1
+  stderr: |
+    gazelle: ERROR: failed to parse annotations: `# gazelle:ignore` requires a value