Skip to content

Commit dfc3756

Browse files
committed
Implement 'update' command
1 parent 496dec1 commit dfc3756

File tree

5 files changed

+160
-33
lines changed

5 files changed

+160
-33
lines changed

build/build.go

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package build
22

33
import (
4-
"bufio"
54
"fmt"
65
"os"
76
"path/filepath"
87
"runtime"
98
"strings"
109

1110
"github.com/Bananenpro/cli"
11+
"github.com/code-game-project/codegame-cli-go/util"
1212
cgExec "github.com/code-game-project/codegame-cli/util/exec"
1313
)
1414

@@ -17,7 +17,7 @@ func BuildClient(projectRoot, gameName, output, url string) error {
1717
if err != nil {
1818
return err
1919
}
20-
packageName, err := getPackageName(projectRoot)
20+
packageName, err := util.GetModuleName(projectRoot)
2121
if err != nil {
2222
return err
2323
}
@@ -58,22 +58,3 @@ func getOutputName(projectRoot, output string) (string, error) {
5858

5959
return output, nil
6060
}
61-
62-
func getPackageName(projectRoot string) (string, error) {
63-
path := filepath.Join(projectRoot, "go.mod")
64-
file, err := os.Open(path)
65-
if err != nil {
66-
return "", cli.Error("Failed to open '%s'", path)
67-
}
68-
69-
scanner := bufio.NewScanner(file)
70-
for scanner.Scan() {
71-
if strings.HasPrefix(scanner.Text(), "module ") {
72-
return strings.TrimSuffix(strings.TrimPrefix(scanner.Text(), "module "), "/"), nil
73-
}
74-
}
75-
if scanner.Err() != nil {
76-
cli.Error("Failed to read '%s': %s", path, scanner.Err())
77-
}
78-
return "", cli.Error("Missing 'module' statement in '%s'", path)
79-
}

main.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func main() {
2020
fmt.Fprintf(os.Stderr, "Usage: %s <command> [...]\n", os.Args[0])
2121
fmt.Fprintln(os.Stderr, "\nCommands:")
2222
fmt.Fprintln(os.Stderr, "\tnew \tCreate a new project.")
23+
fmt.Fprintln(os.Stderr, "\tupdate \tUpdate the current project.")
2324
fmt.Fprintln(os.Stderr, "\trun \tRun the current project.")
2425
fmt.Fprintln(os.Stderr, "\tbuild \tBuild the current project.")
2526
fmt.Fprintln(os.Stderr, "\nOptions:")
@@ -43,6 +44,8 @@ func main() {
4344
switch command {
4445
case "new":
4546
err = newProject(projectName)
47+
case "update":
48+
err = updateProject()
4649
case "run":
4750
err = runProject()
4851
case "build":
@@ -71,7 +74,7 @@ func newProject(projectName string) error {
7174
flagSet.StringVar(&libraryVersion, "library-version", "latest", "The version of the Go library to use, e.g. 0.8")
7275

7376
flagSet.Usage = func() {
74-
fmt.Fprintf(os.Stderr, "Usage: %s run [...]\n", os.Args[0])
77+
fmt.Fprintf(os.Stderr, "Usage: %s new <client|server>\n", os.Args[0])
7578
fmt.Fprintln(os.Stderr, "\nOptions:")
7679
flagSet.PrintDefaults()
7780
}
@@ -96,6 +99,36 @@ func newProject(projectName string) error {
9699
return err
97100
}
98101

102+
func updateProject() error {
103+
flagSet := pflag.NewFlagSet("new", pflag.ExitOnError)
104+
105+
var libraryVersion string
106+
flagSet.StringVar(&libraryVersion, "library-version", "latest", "The version of the Go library to use, e.g. 0.8")
107+
108+
flagSet.Usage = func() {
109+
fmt.Fprintf(os.Stderr, "Usage: %s update\n", os.Args[0])
110+
fmt.Fprintln(os.Stderr, "\nOptions:")
111+
flagSet.PrintDefaults()
112+
}
113+
flagSet.Parse(os.Args[2:])
114+
115+
config, err := cgfile.LoadCodeGameFile("")
116+
if err != nil {
117+
return err
118+
}
119+
120+
switch config.Type {
121+
case "client":
122+
err = client.Update(libraryVersion, config)
123+
case "server":
124+
err = server.Update(libraryVersion)
125+
default:
126+
err = cli.Error("Unknown project type: %s\n", config.Type)
127+
}
128+
129+
return err
130+
}
131+
99132
func runProject() error {
100133
flagSet := pflag.NewFlagSet("run", pflag.ExitOnError)
101134
flagSet.ParseErrorsWhitelist = pflag.ParseErrorsWhitelist{
@@ -149,6 +182,7 @@ func buildProject() error {
149182
flagSet.Usage = func() {
150183
fmt.Fprintf(os.Stderr, "Usage: %s build [...]\n", os.Args[0])
151184
fmt.Fprintln(os.Stderr, "\nOptions:")
185+
fmt.Fprintf(os.Stderr, "`update` must be executed at the root of the project.")
152186
flagSet.PrintDefaults()
153187
}
154188
flagSet.Parse(os.Args[2:])

new/client/client.go

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ package client
33
import (
44
"fmt"
55
"net/http"
6+
"os"
67
"path/filepath"
78
"strings"
89

910
_ "embed"
1011

1112
"github.com/Bananenpro/cli"
1213
"github.com/code-game-project/codegame-cli-go/new"
14+
"github.com/code-game-project/codegame-cli-go/util"
15+
"github.com/code-game-project/codegame-cli/util/cgfile"
1316
"github.com/code-game-project/codegame-cli/util/cggenevents"
1417
"github.com/code-game-project/codegame-cli/util/exec"
1518
"github.com/code-game-project/codegame-cli/util/external"
@@ -63,7 +66,7 @@ func CreateNewClient(projectName, gameName, serverURL, libraryVersion string, ge
6366
}
6467
}
6568

66-
err = createClientTemplate(projectName, module, gameName, serverURL, libraryURL, generateWrappers, eventNames)
69+
err = createClientTemplate(module, gameName, serverURL, libraryURL, generateWrappers, eventNames)
6770
if err != nil {
6871
return err
6972
}
@@ -79,12 +82,62 @@ func CreateNewClient(projectName, gameName, serverURL, libraryVersion string, ge
7982
return nil
8083
}
8184

82-
func createClientTemplate(projectName, modulePath, gameName, serverURL, libraryURL string, wrappers bool, eventNames []string) error {
85+
func Update(libraryVersion string, config *cgfile.CodeGameFileData) error {
86+
libraryURL, libraryTag, err := getClientLibraryURL(libraryVersion)
87+
if err != nil {
88+
return err
89+
}
90+
91+
url := baseURL(config.URL, isSSL(config.URL))
92+
93+
var eventNames []string
94+
cgeVersion, err := cggenevents.GetCGEVersion(url)
95+
if err != nil {
96+
return err
97+
}
98+
99+
eventNames, err = cggenevents.GetEventNames(url, cgeVersion)
100+
if err != nil {
101+
return err
102+
}
103+
104+
module, err := util.GetModuleName("")
105+
if err != nil {
106+
return err
107+
}
108+
109+
err = updateClientTemplate(module, config.Game, config.URL, libraryURL, eventNames)
110+
if err != nil {
111+
return err
112+
}
113+
114+
cli.BeginLoading("Updating dependencies...")
115+
_, err = exec.Execute(true, "go", "get", "-u", "./...")
116+
if err != nil {
117+
return err
118+
}
119+
_, err = exec.Execute(true, "go", "get", fmt.Sprintf("%s@%s", libraryURL, libraryTag))
120+
if err != nil {
121+
return err
122+
}
123+
_, err = exec.Execute(true, "go", "mod", "tidy")
124+
if err != nil {
125+
return err
126+
}
127+
cli.FinishLoading()
128+
return nil
129+
}
130+
131+
func createClientTemplate(modulePath, gameName, serverURL, libraryURL string, wrappers bool, eventNames []string) error {
83132
if !wrappers {
84-
return execClientMainTemplate(projectName, serverURL, libraryURL)
133+
return execClientMainTemplate(serverURL, libraryURL)
85134
}
86135

87-
return execClientWrappersTemplate(projectName, modulePath, gameName, serverURL, libraryURL, eventNames)
136+
return execClientWrappersTemplate(modulePath, gameName, serverURL, libraryURL, eventNames, false)
137+
}
138+
139+
func updateClientTemplate(modulePath, gameName, serverURL, libraryURL string, eventNames []string) error {
140+
return execClientWrappersTemplate(modulePath, gameName, serverURL, libraryURL, eventNames, true)
88141
}
89142

90143
func getClientLibraryURL(clientVersion string) (url string, tag string, err error) {
@@ -101,7 +154,7 @@ func getClientLibraryURL(clientVersion string) (url string, tag string, err erro
101154
return path, tag, nil
102155
}
103156

104-
func execClientMainTemplate(projectName, serverURL, libraryURL string) error {
157+
func execClientMainTemplate(serverURL, libraryURL string) error {
105158
type data struct {
106159
URL string
107160
LibraryURL string
@@ -113,11 +166,21 @@ func execClientMainTemplate(projectName, serverURL, libraryURL string) error {
113166
})
114167
}
115168

116-
func execClientWrappersTemplate(projectName, modulePath, gameName, serverURL, libraryURL string, eventNames []string) error {
169+
func execClientWrappersTemplate(modulePath, gameName, serverURL, libraryURL string, eventNames []string, update bool) error {
117170
gamePackageName := strings.ReplaceAll(strings.ReplaceAll(gameName, "-", ""), "_", "")
118-
119171
gameDir := strings.ReplaceAll(strings.ReplaceAll(gameName, "-", ""), "_", "")
120172

173+
if update {
174+
cli.Warn("This action will ERASE and regenerate ALL files in '%s/'.\nYou will have to manually update your code to work with the new version.", gameDir)
175+
ok, err := cli.YesNo("Continue?", false)
176+
if err != nil || !ok {
177+
return cli.ErrCanceled
178+
}
179+
os.RemoveAll(gameDir)
180+
} else {
181+
cli.Warn("DO NOT EDIT the `%s/` directory. ALL CHANGES WILL BE LOST when running `codegame update`.", gameDir)
182+
}
183+
121184
type event struct {
122185
Name string
123186
PascalName string
@@ -148,12 +211,14 @@ func execClientWrappersTemplate(projectName, modulePath, gameName, serverURL, li
148211
Events: events,
149212
}
150213

151-
err := new.ExecTemplate(wrapperMainTemplate, filepath.Join("main.go"), data)
152-
if err != nil {
153-
return err
214+
if !update {
215+
err := new.ExecTemplate(wrapperMainTemplate, filepath.Join("main.go"), data)
216+
if err != nil {
217+
return err
218+
}
154219
}
155220

156-
err = new.ExecTemplate(wrapperGameTemplate, filepath.Join(gameDir, "game.go"), data)
221+
err := new.ExecTemplate(wrapperGameTemplate, filepath.Join(gameDir, "game.go"), data)
157222
if err != nil {
158223
return err
159224
}

new/server/server.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ func CreateNewServer(projectName, libraryVersion string) error {
6767
return nil
6868
}
6969

70+
func Update(libraryVersion string) error {
71+
cli.Warn("This update might include breaking changes. You will have to manually update your code to work with the new version.")
72+
ok, err := cli.YesNo("Continue?", false)
73+
if err != nil || !ok {
74+
return cli.ErrCanceled
75+
}
76+
77+
cli.BeginLoading("Updating dependencies...")
78+
79+
_, err = exec.Execute(true, "go", "get", "-u", "./...")
80+
if err != nil {
81+
return err
82+
}
83+
84+
cli.FinishLoading()
85+
return nil
86+
}
87+
7088
func createTemplate(projectName, module, libraryURL string) error {
7189
err := executeTemplate(mainTemplate, "main.go", projectName, libraryURL, module)
7290
if err != nil {

util/module.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package util
2+
3+
import (
4+
"bufio"
5+
"os"
6+
"path/filepath"
7+
"strings"
8+
9+
"github.com/Bananenpro/cli"
10+
)
11+
12+
func GetModuleName(projectRoot string) (string, error) {
13+
path := filepath.Join(projectRoot, "go.mod")
14+
file, err := os.Open(path)
15+
if err != nil {
16+
return "", cli.Error("Failed to open '%s'", path)
17+
}
18+
19+
scanner := bufio.NewScanner(file)
20+
for scanner.Scan() {
21+
if strings.HasPrefix(scanner.Text(), "module ") {
22+
return strings.TrimSuffix(strings.TrimPrefix(scanner.Text(), "module "), "/"), nil
23+
}
24+
}
25+
if scanner.Err() != nil {
26+
cli.Error("Failed to read '%s': %s", path, scanner.Err())
27+
}
28+
return "", cli.Error("Missing 'module' statement in '%s'", path)
29+
}

0 commit comments

Comments
 (0)