apidiff: support display of just incompatible changes

Makes the command easier to use in scripts that only want to detect
breaking changes.

Change-Id: Ia898e5716be9c184dbeff4316c2c675e966026f3
Reviewed-on: https://go-review.googlesource.com/c/152937
Reviewed-by: Michael Matloob <matloob@golang.org>
diff --git a/apidiff/report.go b/apidiff/report.go
index 2917d98..454ff35 100644
--- a/apidiff/report.go
+++ b/apidiff/report.go
@@ -20,32 +20,31 @@
 }
 
 func (r Report) Text(w io.Writer) error {
-	var err error
+	if err := r.TextIncompatible(w); err != nil {
+		return err
+	}
+	return r.TextCompatible(w)
+}
 
-	write := func(s string) {
-		if err == nil {
-			_, err = io.WriteString(w, s)
+func (r Report) TextIncompatible(w io.Writer) error {
+	return r.writeMessages(w, "Incompatible changes:", r.Incompatible)
+}
+
+func (r Report) TextCompatible(w io.Writer) error {
+	return r.writeMessages(w, "Compatible changes:", r.Compatible)
+}
+
+func (r Report) writeMessages(w io.Writer, header string, msgs []string) error {
+	if len(msgs) == 0 {
+		return nil
+	}
+	if _, err := fmt.Fprintf(w, "%s\n", header); err != nil {
+		return err
+	}
+	for _, m := range msgs {
+		if _, err := fmt.Fprintf(w, "- %s\n", m); err != nil {
+			return err
 		}
 	}
-
-	writeslice := func(ss []string) {
-		for _, s := range ss {
-			write("- ")
-			write(s)
-			write("\n")
-		}
-	}
-
-	if len(r.Incompatible) > 0 {
-		write("Incompatible changes:\n")
-		writeslice(r.Incompatible)
-	}
-	if len(r.Compatible) > 0 {
-		if len(r.Incompatible) > 0 {
-			write("\n")
-		}
-		write("Compatible changes:\n")
-		writeslice(r.Compatible)
-	}
-	return err
+	return nil
 }
diff --git a/cmd/apidiff/main.go b/cmd/apidiff/main.go
index 5243e03..724881d 100644
--- a/cmd/apidiff/main.go
+++ b/cmd/apidiff/main.go
@@ -12,7 +12,10 @@
 	"golang.org/x/tools/go/packages"
 )
 
-var exportDataOutfile = flag.String("w", "", "file for export data")
+var (
+	exportDataOutfile = flag.String("w", "", "file for export data")
+	incompatibleOnly  = flag.Bool("incompatible", false, "display only incompatible changes")
+)
 
 func main() {
 	flag.Usage = func() {
@@ -43,7 +46,13 @@
 		newpkg := mustLoadOrRead(flag.Arg(1))
 
 		report := apidiff.Changes(oldpkg, newpkg)
-		if err := report.Text(os.Stdout); err != nil {
+		var err error
+		if *incompatibleOnly {
+			err = report.TextIncompatible(os.Stdout)
+		} else {
+			err = report.Text(os.Stdout)
+		}
+		if err != nil {
 			die("writing report: %v", err)
 		}
 	}