1package main
2
3import (
4	"fmt"
5	"go/build"
6	"io/ioutil"
7	"os"
8	"path"
9	"path/filepath"
10	"strings"
11
12	"github.com/pkg/errors"
13)
14
15const (
16	pkgGocheck      = "github.com/go-check/check"
17	pkgGopkgGocheck = "gopkg.in/check.v1"
18)
19
20var allTestingTPkgs = append(
21	allTestifyPks,
22	pkgGocheck,
23	pkgGopkgGocheck,
24)
25
26func newFakeImporter() (*fakeImporter, error) {
27	tmpDir, err := ioutil.TempDir("", "gty-migrate-from-testify")
28	err = errors.Wrapf(err, "failed to create temporary directory")
29	return &fakeImporter{tmpDir: tmpDir}, err
30}
31
32type fakeImporter struct {
33	tmpDir string
34}
35
36func (f *fakeImporter) Cleanup() error {
37	return os.RemoveAll(f.tmpDir)
38}
39
40func (f *fakeImporter) Import(
41	ctx *build.Context,
42	path string,
43	dir string,
44	mode build.ImportMode,
45) (*build.Package, error) {
46	pkg, err := ctx.Import(path, dir, mode)
47	if err == nil {
48		return pkg, err
49	}
50
51	for _, pkgName := range allTestingTPkgs {
52		if pkgName == path {
53			return importStubPackage(f.tmpDir, pkgName)
54		}
55	}
56
57	return pkg, err
58}
59
60func importStubPackage(tmpDir string, importPath string) (*build.Package, error) {
61	pkgName := strings.TrimSuffix(path.Base(importPath), ".v1")
62	pkgFilePath := filepath.Join(tmpDir, pkgName)
63
64	if err := os.MkdirAll(pkgFilePath, 0755); err != nil {
65		return nil, errors.Wrapf(err, "failed to create stub package directory")
66	}
67
68	const filename = "fixture.go"
69	if err := writeStubFile(filepath.Join(pkgFilePath, filename), pkgName); err != nil {
70		return nil, errors.Wrapf(err, "failed to write stub file")
71	}
72
73	return &build.Package{
74		Dir:        pkgFilePath,
75		Name:       pkgName,
76		ImportPath: importPath,
77		GoFiles:    []string{filename},
78	}, nil
79}
80
81func writeStubFile(path string, pkgName string) error {
82	content := []byte(fmt.Sprintf(stubFixtureContent, pkgName))
83	return ioutil.WriteFile(path, content, 0644)
84}
85
86const stubFixtureContent = `
87package %s
88
89type TestingT interface {
90	Errorf(format string, args ...interface{})
91	FailNow()
92}
93
94func New(t TestingT) *Assertions {
95	return &Assertions{}
96}
97
98type Assertions struct {}
99
100type C struct{}
101
102`
103