import.go

  1package templates
  2
  3import (
  4	"fmt"
  5	"go/build"
  6	"strconv"
  7
  8	"github.com/99designs/gqlgen/internal/gopath"
  9)
 10
 11type Import struct {
 12	Name  string
 13	Path  string
 14	Alias string
 15}
 16
 17type Imports struct {
 18	imports []*Import
 19	destDir string
 20}
 21
 22func (i *Import) String() string {
 23	if i.Alias == i.Name {
 24		return strconv.Quote(i.Path)
 25	}
 26
 27	return i.Alias + " " + strconv.Quote(i.Path)
 28}
 29
 30func (s *Imports) String() string {
 31	res := ""
 32	for i, imp := range s.imports {
 33		if i != 0 {
 34			res += "\n"
 35		}
 36		res += imp.String()
 37	}
 38	return res
 39}
 40
 41func (s *Imports) Reserve(path string, aliases ...string) string {
 42	if path == "" {
 43		panic("empty ambient import")
 44	}
 45
 46	// if we are referencing our own package we dont need an import
 47	if gopath.MustDir2Import(s.destDir) == path {
 48		return ""
 49	}
 50
 51	pkg, err := build.Default.Import(path, s.destDir, 0)
 52	if err != nil {
 53		panic(err)
 54	}
 55
 56	var alias string
 57	if len(aliases) != 1 {
 58		alias = pkg.Name
 59	} else {
 60		alias = aliases[0]
 61	}
 62
 63	if existing := s.findByPath(path); existing != nil {
 64		panic("ambient import already exists")
 65	}
 66
 67	if alias := s.findByAlias(alias); alias != nil {
 68		panic("ambient import collides on an alias")
 69	}
 70
 71	s.imports = append(s.imports, &Import{
 72		Name:  pkg.Name,
 73		Path:  path,
 74		Alias: alias,
 75	})
 76
 77	return ""
 78}
 79
 80func (s *Imports) Lookup(path string) string {
 81	if path == "" {
 82		return ""
 83	}
 84
 85	// if we are referencing our own package we dont need an import
 86	if gopath.MustDir2Import(s.destDir) == path {
 87		return ""
 88	}
 89
 90	if existing := s.findByPath(path); existing != nil {
 91		return existing.Alias
 92	}
 93
 94	pkg, err := build.Default.Import(path, s.destDir, 0)
 95	if err != nil {
 96		panic(err)
 97	}
 98
 99	imp := &Import{
100		Name: pkg.Name,
101		Path: path,
102	}
103	s.imports = append(s.imports, imp)
104
105	alias := imp.Name
106	i := 1
107	for s.findByAlias(alias) != nil {
108		alias = imp.Name + strconv.Itoa(i)
109		i++
110		if i > 10 {
111			panic(fmt.Errorf("too many collisions, last attempt was %s", alias))
112		}
113	}
114	imp.Alias = alias
115
116	return imp.Alias
117}
118
119func (s Imports) findByPath(importPath string) *Import {
120	for _, imp := range s.imports {
121		if imp.Path == importPath {
122			return imp
123		}
124	}
125	return nil
126}
127
128func (s Imports) findByAlias(alias string) *Import {
129	for _, imp := range s.imports {
130		if imp.Alias == alias {
131			return imp
132		}
133	}
134	return nil
135}