internal/txtar: replace with golang.org/x/tools/txtar

Change-Id: I31580c355feee65b3c63b3fe977f216070ce8a21
Reviewed-on: https://go-review.googlesource.com/c/mod/+/207907
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/go.mod b/go.mod
index 9d78a76..417cd80 100644
--- a/go.mod
+++ b/go.mod
@@ -4,5 +4,6 @@
 
 require (
 	golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
+	golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e
 	golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898
 )
diff --git a/go.sum b/go.sum
index 249ed71..6cf8709 100644
--- a/go.sum
+++ b/go.sum
@@ -2,8 +2,13 @@
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e h1:aZzprAO9/8oim3qStq3wc1Xuxx4QmAGriC4VU4ojemQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/internal/txtar/archive.go b/internal/txtar/archive.go
deleted file mode 100644
index c384f33..0000000
--- a/internal/txtar/archive.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package txtar implements a trivial text-based file archive format.
-//
-// The goals for the format are:
-//
-//	- be trivial enough to create and edit by hand.
-//	- be able to store trees of text files describing go command test cases.
-//	- diff nicely in git history and code reviews.
-//
-// Non-goals include being a completely general archive format,
-// storing binary data, storing file modes, storing special files like
-// symbolic links, and so on.
-//
-// Txtar format
-//
-// A txtar archive is zero or more comment lines and then a sequence of file entries.
-// Each file entry begins with a file marker line of the form "-- FILENAME --"
-// and is followed by zero or more file content lines making up the file data.
-// The comment or file content ends at the next file marker line.
-// The file marker line must begin with the three-byte sequence "-- "
-// and end with the three-byte sequence " --", but the enclosed
-// file name can be surrounding by additional white space,
-// all of which is stripped.
-//
-// If the txtar file is missing a trailing newline on the final line,
-// parsers should consider a final newline to be present anyway.
-//
-// There are no possible syntax errors in a txtar archive.
-package txtar
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"strings"
-)
-
-// An Archive is a collection of files.
-type Archive struct {
-	Comment []byte
-	Files   []File
-}
-
-// A File is a single file in an archive.
-type File struct {
-	Name string // name of file ("foo/bar.txt")
-	Data []byte // text content of file
-}
-
-// Format returns the serialized form of an Archive.
-// It is assumed that the Archive data structure is well-formed:
-// a.Comment and all a.File[i].Data contain no file marker lines,
-// and all a.File[i].Name is non-empty.
-func Format(a *Archive) []byte {
-	var buf bytes.Buffer
-	buf.Write(fixNL(a.Comment))
-	for _, f := range a.Files {
-		fmt.Fprintf(&buf, "-- %s --\n", f.Name)
-		buf.Write(fixNL(f.Data))
-	}
-	return buf.Bytes()
-}
-
-// ParseFile parses the named file as an archive.
-func ParseFile(file string) (*Archive, error) {
-	data, err := ioutil.ReadFile(file)
-	if err != nil {
-		return nil, err
-	}
-	return Parse(data), nil
-}
-
-// Parse parses the serialized form of an Archive.
-// The returned Archive holds slices of data.
-func Parse(data []byte) *Archive {
-	a := new(Archive)
-	var name string
-	a.Comment, name, data = findFileMarker(data)
-	for name != "" {
-		f := File{name, nil}
-		f.Data, name, data = findFileMarker(data)
-		a.Files = append(a.Files, f)
-	}
-	return a
-}
-
-var (
-	newlineMarker = []byte("\n-- ")
-	marker        = []byte("-- ")
-	markerEnd     = []byte(" --")
-)
-
-// findFileMarker finds the next file marker in data,
-// extracts the file name, and returns the data before the marker,
-// the file name, and the data after the marker.
-// If there is no next marker, findFileMarker returns before = fixNL(data), name = "", after = nil.
-func findFileMarker(data []byte) (before []byte, name string, after []byte) {
-	var i int
-	for {
-		if name, after = isMarker(data[i:]); name != "" {
-			return data[:i], name, after
-		}
-		j := bytes.Index(data[i:], newlineMarker)
-		if j < 0 {
-			return fixNL(data), "", nil
-		}
-		i += j + 1 // positioned at start of new possible marker
-	}
-}
-
-// isMarker checks whether data begins with a file marker line.
-// If so, it returns the name from the line and the data after the line.
-// Otherwise it returns name == "" with an unspecified after.
-func isMarker(data []byte) (name string, after []byte) {
-	if !bytes.HasPrefix(data, marker) {
-		return "", nil
-	}
-	if i := bytes.IndexByte(data, '\n'); i >= 0 {
-		data, after = data[:i], data[i+1:]
-	}
-	if !bytes.HasSuffix(data, markerEnd) {
-		return "", nil
-	}
-	return strings.TrimSpace(string(data[len(marker) : len(data)-len(markerEnd)])), after
-}
-
-// If data is empty or ends in \n, fixNL returns data.
-// Otherwise fixNL returns a new slice consisting of data with a final \n added.
-func fixNL(data []byte) []byte {
-	if len(data) == 0 || data[len(data)-1] == '\n' {
-		return data
-	}
-	d := make([]byte, len(data)+1)
-	copy(d, data)
-	d[len(data)] = '\n'
-	return d
-}
diff --git a/internal/txtar/archive_test.go b/internal/txtar/archive_test.go
deleted file mode 100644
index 3f734f6..0000000
--- a/internal/txtar/archive_test.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package txtar
-
-import (
-	"bytes"
-	"fmt"
-	"reflect"
-	"testing"
-)
-
-var tests = []struct {
-	name   string
-	text   string
-	parsed *Archive
-}{
-	{
-		name: "basic",
-		text: `comment1
-comment2
--- file1 --
-File 1 text.
--- foo ---
-More file 1 text.
--- file 2 --
-File 2 text.
--- empty --
--- noNL --
-hello world`,
-		parsed: &Archive{
-			Comment: []byte("comment1\ncomment2\n"),
-			Files: []File{
-				{"file1", []byte("File 1 text.\n-- foo ---\nMore file 1 text.\n")},
-				{"file 2", []byte("File 2 text.\n")},
-				{"empty", []byte{}},
-				{"noNL", []byte("hello world\n")},
-			},
-		},
-	},
-}
-
-func Test(t *testing.T) {
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			a := Parse([]byte(tt.text))
-			if !reflect.DeepEqual(a, tt.parsed) {
-				t.Fatalf("Parse: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed))
-			}
-			text := Format(a)
-			a = Parse(text)
-			if !reflect.DeepEqual(a, tt.parsed) {
-				t.Fatalf("Parse after Format: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed))
-			}
-		})
-	}
-}
-
-func shortArchive(a *Archive) string {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "comment: %q\n", a.Comment)
-	for _, f := range a.Files {
-		fmt.Fprintf(&buf, "file %q: %q\n", f.Name, f.Data)
-	}
-	return buf.String()
-}
diff --git a/zip/zip_test.go b/zip/zip_test.go
index ec5100f..fa32157 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -21,10 +21,10 @@
 	"testing"
 	"time"
 
-	"golang.org/x/mod/internal/txtar"
 	"golang.org/x/mod/module"
 	"golang.org/x/mod/sumdb/dirhash"
 	modzip "golang.org/x/mod/zip"
+	"golang.org/x/tools/txtar"
 )
 
 const emptyHash = "h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="