1
2
3
4
5
6
7
8
9
10
11
12
13
14 package main
15
16 import (
17 "os"
18 "reflect"
19 "sort"
20
21 "github.com/go-kivik/kivik/v4"
22 "github.com/go-kivik/kivik/v4/driver"
23 )
24
25 var clientSkips = map[string]struct{}{
26 "Driver": {},
27 "DSN": {},
28 "CreateDB": {},
29 }
30
31 var dbSkips = map[string]struct{}{
32 "Close": {},
33 "Client": {},
34 "Err": {},
35 "Name": {},
36 "Search": {},
37 "SearchAnalyze": {},
38 "SearchInfo": {},
39 }
40
41 func main() {
42 initTemplates(os.Args[1])
43 const openPerms = 0o777
44 if err := os.Mkdir("./other", openPerms); err != nil && !os.IsExist(err) {
45 panic(err)
46 }
47 if err := client(); err != nil {
48 panic(err)
49 }
50 if err := db(); err != nil {
51 panic(err)
52 }
53 }
54
55 type fullClient interface {
56 driver.Client
57 driver.DBsStatser
58 driver.AllDBsStatser
59 driver.Pinger
60 driver.Sessioner
61 driver.Cluster
62 driver.ClientCloser
63 driver.ClientReplicator
64 driver.DBUpdater
65 driver.Configer
66 }
67
68 func client() error {
69 dMethods, err := parseMethods(struct{ X fullClient }{}, false, clientSkips)
70 if err != nil {
71 return err
72 }
73
74 client, err := parseMethods(struct{ X *kivik.Client }{}, true, clientSkips)
75 if err != nil {
76 return err
77 }
78 same, cm, dm := compareMethods(client, dMethods)
79
80 if err := renderExpectationsGo("clientexpectations_gen.go", append(same, dm...)); err != nil {
81 return err
82 }
83 if err := renderClientGo("client_gen.go", append(same, dm...)); err != nil {
84 return err
85 }
86 return renderMockGo("clientmock_gen.go", append(same, cm...))
87 }
88
89 type fullDB interface {
90 driver.DB
91 driver.DocCreator
92 driver.AttachmentMetaGetter
93 driver.BulkDocer
94 driver.BulkGetter
95 driver.Copier
96 driver.DesignDocer
97 driver.Finder
98 driver.Flusher
99 driver.LocalDocer
100 driver.RevGetter
101 driver.Purger
102 driver.RevsDiffer
103 driver.PartitionedDB
104 driver.SecurityDB
105 driver.OpenRever
106 }
107
108 func db() error {
109 dMethods, err := parseMethods(struct{ X fullDB }{}, false, dbSkips)
110 if err != nil {
111 return err
112 }
113
114 client, err := parseMethods(struct{ X *kivik.DB }{}, true, dbSkips)
115 if err != nil {
116 return err
117 }
118 same, cm, dm := compareMethods(client, dMethods)
119
120 for _, method := range same {
121 method.DBMethod = true
122 }
123 for _, method := range dm {
124 method.DBMethod = true
125 }
126 for _, method := range cm {
127 method.DBMethod = true
128 }
129
130 if err := renderExpectationsGo("dbexpectations_gen.go", append(same, dm...)); err != nil {
131 return err
132 }
133 if err := renderClientGo("db_gen.go", append(same, dm...)); err != nil {
134 return err
135 }
136 return renderMockGo("dbmock_gen.go", append(same, cm...))
137 }
138
139 func compareMethods(client, driver []*method) (same []*method, differentClient []*method, differentDriver []*method) {
140 dMethods := toMap(driver)
141 cMethods := toMap(client)
142 sameMethods := make(map[string]*method)
143 for name, method := range dMethods {
144 if cMethod, ok := cMethods[name]; ok {
145 if reflect.DeepEqual(cMethod, method) {
146 sameMethods[name] = method
147 delete(dMethods, name)
148 delete(cMethods, name)
149 }
150 } else {
151 delete(dMethods, name)
152 delete(cMethods, name)
153 }
154 }
155 return toSlice(sameMethods), toSlice(cMethods), toSlice(dMethods)
156 }
157
158 func toSlice(methods map[string]*method) []*method {
159 result := make([]*method, 0, len(methods))
160 for _, method := range methods {
161 result = append(result, method)
162 }
163 sort.Slice(result, func(i, j int) bool {
164 return result[i].Name < result[j].Name
165 })
166 return result
167 }
168
169 func toMap(methods []*method) map[string]*method {
170 result := make(map[string]*method, len(methods))
171 for _, method := range methods {
172 result[method.Name] = method
173 }
174 return result
175 }
176
View as plain text