Skip to content

Commit 0001065

Browse files
committed
Implement Go helper function generator
1 parent 8ef8c0d commit 0001065

File tree

11 files changed

+459
-90
lines changed

11 files changed

+459
-90
lines changed

commands/new.go

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8-
"io"
98
"net/http"
109
"os"
1110
"path/filepath"
@@ -117,7 +116,7 @@ func newClient(projectName string) error {
117116
if err != nil {
118117
return err
119118
}
120-
cgeVersion, err := getCGEVersion(baseURL(url, ssl))
119+
cgeVersion, err := external.GetCGEVersion(baseURL(url, ssl))
121120
if err != nil {
122121
return err
123122
}
@@ -133,23 +132,30 @@ func newClient(projectName string) error {
133132
}
134133
}
135134

135+
switch language {
136+
case "go":
137+
err = newGoClient(projectName, name, url, cgVersion, cgeVersion)
138+
default:
139+
return cli.Error("Unsupported language: %s", language)
140+
}
141+
if err != nil {
142+
return err
143+
}
144+
136145
eventsOutput := projectName
137146
if language == "go" {
138147
eventsOutput = filepath.Join(projectName, strings.ReplaceAll(strings.ReplaceAll(name, "-", ""), "_", ""))
139148
}
140149

150+
cli.Begin("Generating event definitions...")
141151
err = external.CGGenEvents(eventsOutput, baseURL(url, ssl), cgeVersion, language)
142152
if err != nil {
143153
cli.Error("Failed to generate event definitions: %s", err)
154+
return err
144155
}
156+
cli.Finish()
145157

146-
switch language {
147-
case "go":
148-
err = newGoClient(projectName, url, cgVersion)
149-
default:
150-
return cli.Error("Unsupported language: %s", language)
151-
}
152-
return err
158+
return nil
153159
}
154160

155161
func git(projectName string) error {
@@ -334,47 +340,24 @@ func getCodeGameInfo(baseURL string) (string, string, error) {
334340
return data.Name, data.CGVersion, nil
335341
}
336342

337-
func getCGEVersion(baseURL string) (string, error) {
338-
res, err := http.Get(baseURL + "/events")
339-
if err != nil || res.StatusCode != http.StatusOK || !external.HasContentType(res.Header, "text/plain") {
340-
return "", cli.Error("Couldn't access /events endpoint.")
341-
}
342-
defer res.Body.Close()
343-
344-
data, err := io.ReadAll(res.Body)
343+
func execTemplate(templateText, path string, data any) error {
344+
err := os.MkdirAll(filepath.Join(filepath.Dir(path)), 0755)
345345
if err != nil {
346-
return "", cli.Error("Couldn't read /events file.")
346+
return err
347347
}
348-
return parseCGEVersion([]rune(string(data))), nil
349-
}
350348

351-
func parseCGEVersion(runes []rune) string {
352-
index := 0
353-
commentNestingLevel := 0
354-
for index < len(runes) && (runes[index] == ' ' || runes[index] == '\r' || runes[index] == '\n' || runes[index] == '\t' || (index < len(runes)-1 && runes[index] == '/' && runes[index+1] == '*') || (index < len(runes)-1 && runes[index] == '*' && runes[index+1] == '/') || (index < len(runes)-1 && runes[index] == '/' && runes[index+1] == '/') || commentNestingLevel > 0) {
355-
if runes[index] == '/' {
356-
if runes[index+1] == '/' {
357-
for index < len(runes) && runes[index] != '\n' {
358-
index++
359-
}
360-
} else {
361-
commentNestingLevel++
362-
}
363-
}
364-
if runes[index] == '*' {
365-
commentNestingLevel--
366-
}
367-
index++
349+
tmpl, err := template.New(path).Parse(templateText)
350+
if err != nil {
351+
return err
368352
}
369353

370-
words := strings.Fields(string(runes[index:]))
371-
for i, w := range words {
372-
if w == "version" && i < len(words)-1 {
373-
return words[i+1]
374-
}
354+
file, err := os.Create(filepath.Join(path))
355+
if err != nil {
356+
return err
375357
}
358+
defer file.Close()
376359

377-
return ""
360+
return tmpl.Execute(file, data)
378361
}
379362

380363
func baseURL(domain string, ssl bool) string {

commands/new_go.go

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@ package commands
22

33
import (
44
"fmt"
5-
"os"
65
"path/filepath"
76
"strings"
8-
"text/template"
97

108
_ "embed"
119

1210
"github.com/code-game-project/codegame-cli/cli"
1311
"github.com/code-game-project/codegame-cli/external"
1412
)
1513

16-
//go:embed templates/go/client/main.go.tmpl
17-
var goClientMainTemplate string
18-
1914
//go:embed templates/go/server/main.go.tmpl
2015
var goServerMainTemplate string
2116

@@ -25,10 +20,10 @@ var goServerGameTemplate string
2520
//go:embed templates/go/server/events.cge.tmpl
2621
var goServerCGETemplate string
2722

28-
//go:embed templates/go/server/events.go.tmpl
23+
//go:embed templates/go/server/event_definitions.go.tmpl
2924
var goServerEventsTemplate string
3025

31-
func newGoClient(projectName, serverURL, cgVersion string) error {
26+
func newGoClient(projectName, gameName, serverURL, cgVersion, cgeVersion string) error {
3227
module, err := cli.Input("Project module path:")
3328
if err != nil {
3429
return err
@@ -42,12 +37,25 @@ func newGoClient(projectName, serverURL, cgVersion string) error {
4237
return err
4338
}
4439

45-
cli.Begin("Installing correct go-client version...")
4640
libraryURL, libraryTag, err := getGoClientLibraryURL(projectName, cgVersion)
4741
if err != nil {
4842
return err
4943
}
5044

45+
cgeMajor, cgeMinor, _, err := external.ParseVersion(cgeVersion)
46+
if err != nil {
47+
return cli.Error(err.Error())
48+
}
49+
50+
wrappers := false
51+
if cgeMajor > 0 || cgeMinor >= 3 {
52+
wrappers, err = cli.YesNo("Do you want to generate helper functions?", true)
53+
if err != nil {
54+
return err
55+
}
56+
}
57+
58+
cli.Begin("Installing correct go-client version...")
5159
out, err = external.ExecuteInDirHidden(projectName, "go", "get", fmt.Sprintf("%s@%s", libraryURL, libraryTag))
5260
if err != nil {
5361
if out != "" {
@@ -58,7 +66,7 @@ func newGoClient(projectName, serverURL, cgVersion string) error {
5866
cli.Finish()
5967

6068
cli.Begin("Creating project template...")
61-
err = createGoClientTemplate(projectName, serverURL, libraryURL)
69+
err = createGoClientTemplate(libraryTag, projectName, module, gameName, serverURL, libraryURL, cgeVersion, wrappers)
6270
if err != nil {
6371
return err
6472
}
@@ -89,27 +97,12 @@ func newGoClient(projectName, serverURL, cgVersion string) error {
8997
return nil
9098
}
9199

92-
func createGoClientTemplate(projectName, serverURL, libraryURL string) error {
93-
tmpl, err := template.New("main.go").Parse(goClientMainTemplate)
94-
if err != nil {
95-
return err
96-
}
97-
98-
file, err := os.Create(filepath.Join(projectName, "main.go"))
100+
func createGoClientTemplate(libraryTag, projectName, modulePath, gameName, serverURL, libraryURL, cgeVersion string, wrappers bool) error {
101+
err := createGoClientTemplatev0_8(projectName, modulePath, gameName, serverURL, libraryURL, cgeVersion, wrappers)
99102
if err != nil {
100-
return err
101-
}
102-
defer file.Close()
103-
104-
type data struct {
105-
URL string
106-
LibraryURL string
103+
cli.Error(err.Error())
107104
}
108-
109-
return tmpl.Execute(file, data{
110-
URL: serverURL,
111-
LibraryURL: libraryURL,
112-
})
105+
return err
113106
}
114107

115108
func getGoClientLibraryURL(projectName, cgVersion string) (url string, tag string, err error) {
@@ -215,26 +208,10 @@ func createGoServerTemplate(projectName, module, cgeVersion, libraryURL string)
215208
return err
216209
}
217210

218-
return executeGoServerTemplate(goServerEventsTemplate, filepath.Join(packageName, "events.go"), projectName, cgeVersion, libraryURL, module)
211+
return executeGoServerTemplate(goServerEventsTemplate, filepath.Join(packageName, "event_definitions.go"), projectName, cgeVersion, libraryURL, module)
219212
}
220213

221214
func executeGoServerTemplate(templateText, fileName, projectName, cgeVersion, libraryURL, modulePath string) error {
222-
tmpl, err := template.New(fileName).Parse(templateText)
223-
if err != nil {
224-
return err
225-
}
226-
227-
err = os.MkdirAll(filepath.Join(projectName, filepath.Dir(fileName)), 0755)
228-
if err != nil {
229-
return err
230-
}
231-
232-
file, err := os.Create(filepath.Join(projectName, fileName))
233-
if err != nil {
234-
return err
235-
}
236-
defer file.Close()
237-
238215
type data struct {
239216
Name string
240217
PackageName string
@@ -244,7 +221,7 @@ func executeGoServerTemplate(templateText, fileName, projectName, cgeVersion, li
244221
ModulePath string
245222
}
246223

247-
return tmpl.Execute(file, data{
224+
return execTemplate(templateText, filepath.Join(projectName, fileName), data{
248225
Name: projectName,
249226
PackageName: strings.ReplaceAll(strings.ReplaceAll(projectName, "_", ""), "-", ""),
250227
SnakeCaseName: strings.ReplaceAll(projectName, "-", "_"),

commands/new_go_client_v0_8.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package commands
2+
3+
import (
4+
_ "embed"
5+
"path/filepath"
6+
"strings"
7+
8+
"github.com/code-game-project/codegame-cli/external"
9+
)
10+
11+
//go:embed templates/go/client/v0.8/main.go.tmpl
12+
var goClientMainTemplatev0_8 string
13+
14+
//go:embed templates/go/client/v0.8/wrappers/main.go.tmpl
15+
var goClientWrapperMainTemplatev0_8 string
16+
17+
//go:embed templates/go/client/v0.8/wrappers/game.go.tmpl
18+
var goClientWrapperGameTemplatev0_8 string
19+
20+
//go:embed templates/go/client/v0.8/wrappers/events.go.tmpl
21+
var goClientWrapperEventsTemplatev0_8 string
22+
23+
func createGoClientTemplatev0_8(projectName, modulePath, gameName, serverURL, libraryURL, cgeVersion string, wrappers bool) error {
24+
if !wrappers {
25+
return execGoClientMainTemplatev0_8(projectName, serverURL, libraryURL)
26+
}
27+
28+
return execGoClientWrappersv0_8(projectName, modulePath, gameName, serverURL, libraryURL, cgeVersion)
29+
}
30+
31+
func execGoClientMainTemplatev0_8(projectName, serverURL, libraryURL string) error {
32+
type data struct {
33+
URL string
34+
LibraryURL string
35+
}
36+
37+
return execTemplate(goClientMainTemplatev0_8, filepath.Join(projectName, "main.go"), data{
38+
URL: serverURL,
39+
LibraryURL: libraryURL,
40+
})
41+
}
42+
43+
func execGoClientWrappersv0_8(projectName, modulePath, gameName, serverURL, libraryURL, cgeVersion string) error {
44+
gamePackageName := strings.ReplaceAll(strings.ReplaceAll(gameName, "-", ""), "_", "")
45+
46+
gameDir := filepath.Join(projectName, strings.ReplaceAll(strings.ReplaceAll(gameName, "-", ""), "_", ""))
47+
48+
eventNames, err := external.GetEventNames(baseURL(serverURL, isSSL(serverURL)), cgeVersion)
49+
if err != nil {
50+
return err
51+
}
52+
53+
type event struct {
54+
Name string
55+
PascalName string
56+
}
57+
58+
events := make([]event, len(eventNames))
59+
for i, e := range eventNames {
60+
pascal := strings.ReplaceAll(e, "_", " ")
61+
pascal = strings.Title(pascal)
62+
pascal = strings.ReplaceAll(pascal, " ", "")
63+
events[i] = event{
64+
Name: e,
65+
PascalName: pascal,
66+
}
67+
}
68+
69+
data := struct {
70+
URL string
71+
LibraryURL string
72+
PackageName string
73+
ModulePath string
74+
Events []event
75+
}{
76+
URL: serverURL,
77+
LibraryURL: libraryURL,
78+
PackageName: gamePackageName,
79+
ModulePath: modulePath,
80+
Events: events,
81+
}
82+
83+
err = execTemplate(goClientWrapperMainTemplatev0_8, filepath.Join(projectName, "main.go"), data)
84+
if err != nil {
85+
return err
86+
}
87+
88+
err = execTemplate(goClientWrapperGameTemplatev0_8, filepath.Join(gameDir, "game.go"), data)
89+
if err != nil {
90+
return err
91+
}
92+
93+
err = execTemplate(goClientWrapperEventsTemplatev0_8, filepath.Join(gameDir, "events.go"), data)
94+
if err != nil {
95+
return err
96+
}
97+
98+
return nil
99+
}

0 commit comments

Comments
 (0)