@@ -2,13 +2,18 @@ package main
2
2
3
3
import (
4
4
"fmt"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
5
8
9
+ "github.com/Bananenpro/cli"
6
10
"github.com/code-game-project/go-utils/cgfile"
11
+ "github.com/code-game-project/go-utils/exec"
7
12
"github.com/code-game-project/go-utils/modules"
13
+ cp "github.com/otiai10/copy"
8
14
)
9
15
10
16
func Build () error {
11
- panic ("not implemented" )
12
17
config , err := cgfile .LoadCodeGameFile ("" )
13
18
if err != nil {
14
19
return err
@@ -18,21 +23,115 @@ func Build() error {
18
23
if err != nil {
19
24
return err
20
25
}
26
+ if data .Output == "" {
27
+ data .Output = "build"
28
+ }
29
+
30
+ typescript := data .Lang == "ts"
31
+
32
+ runtime , _ := config .LangConfig ["runtime" ].(string )
33
+ if runtime != "node" && runtime != "bundler" && (typescript || runtime != "browser" ) {
34
+ return fmt .Errorf ("Invalid runtime: '%s'" , runtime )
35
+ }
21
36
22
37
switch config .Type {
23
38
case "client" :
24
- return buildClient (config .Game , data .Output , config .URL )
39
+ return buildClient (config .Game , data .Output , config .URL , typescript , runtime )
25
40
case "server" :
26
- return buildServer (data . Output )
41
+ return buildServer ()
27
42
default :
28
43
return fmt .Errorf ("Unknown project type: %s" , config .Type )
29
44
}
30
45
}
31
46
32
- func buildClient (gameName , output , url string ) error {
47
+ func buildClient (gameName , output , url string , typescript bool , runtime string ) error {
48
+ yes , err := cli .YesNo (fmt .Sprintf ("The '%s' directory will be completely overridden. Continue?" , output ), false )
49
+ if err != nil || ! yes {
50
+ return cli .ErrCanceled
51
+ }
52
+ os .RemoveAll (output )
53
+ err = os .MkdirAll (output , 0o755 )
54
+ if err != nil {
55
+ return fmt .Errorf ("Failed to create output directory: %w" , err )
56
+ }
57
+
58
+ cli .BeginLoading ("Building..." )
59
+
60
+ if runtime == "node" {
61
+ if typescript {
62
+ _ , err = exec .Execute (true , "npx" , "tsc" , "--outDir" , output )
63
+ if err != nil {
64
+ return err
65
+ }
66
+ } else {
67
+ err = cp .Copy ("src" , output , cp.Options {
68
+ OnSymlink : func (src string ) cp.SymlinkAction {
69
+ return cp .Deep
70
+ },
71
+ })
72
+ if err != nil {
73
+ return fmt .Errorf ("Failed to copy source files to output directory: %s" , err )
74
+ }
75
+ }
76
+ } else if runtime == "bundler" {
77
+ gameJSPath := filepath .Join ("src" , gameName , "game.js" )
78
+ if typescript {
79
+ gameJSPath = filepath .Join ("src" , gameName , "game.ts" )
80
+ }
81
+ err = replaceInFile (gameJSPath , "throw 'Query parameter \" game_url\" must be set.'" , fmt .Sprintf ("return '%s'" , url ))
82
+ if err != nil {
83
+ return err
84
+ }
85
+
86
+ _ , err = exec .Execute (true , "npx" , "parcel" , "build" , "--dist-dir" , output , "src/index.html" )
87
+ if err != nil {
88
+ return err
89
+ }
90
+
91
+ err = replaceInFile (gameJSPath , fmt .Sprintf ("return '%s'" , url ), "throw 'Query parameter \" game_url\" must be set.'" )
92
+ if err != nil {
93
+ return err
94
+ }
95
+ } else if runtime == "browser" {
96
+ err = cp .Copy ("." , output , cp.Options {
97
+ Skip : func (src string ) (bool , error ) {
98
+ return src == "build" || (src != "node_modules" && strings .HasPrefix (src , "node_modules" ) && ! strings .Contains (src , "@code-game-project" )) || src == ".codegame.json" || src == "package.json" || src == "package-lock.json" , nil
99
+ },
100
+ })
101
+ if err != nil {
102
+ return fmt .Errorf ("Failed to copy source files to output directory: %s" , err )
103
+ }
104
+ }
105
+
106
+ if runtime != "bundler" {
107
+ gameJSPath := filepath .Join (output , gameName , "game.js" )
108
+ if runtime == "node" {
109
+ err = replaceInFile (gameJSPath , "throw 'Environment variable `CG_GAME_URL` must be set.'" , fmt .Sprintf ("return '%s'" , url ))
110
+ } else {
111
+ err = replaceInFile (gameJSPath , "throw 'Query parameter \" game_url\" must be set.'" , fmt .Sprintf ("return '%s'" , url ))
112
+ }
113
+ }
114
+ if err != nil {
115
+ return err
116
+ }
117
+ cli .FinishLoading ()
118
+ return nil
119
+ }
120
+
121
+ func replaceInFile (filename , old , new string ) error {
122
+ content , err := os .ReadFile (filename )
123
+ if err != nil {
124
+ return fmt .Errorf ("Failed to replace '%s' with '%s' in '%s': %s" , old , new , filename , err )
125
+ }
126
+ content = []byte (strings .ReplaceAll (string (content ), old , new ))
127
+ err = os .WriteFile (filename , content , 0o644 )
128
+ if err != nil {
129
+ return fmt .Errorf ("Failed to replace '%s' with '%s' in '%s': %s" , old , new , filename , err )
130
+ }
33
131
return nil
34
132
}
35
133
36
- func buildServer (output string ) error {
134
+ func buildServer () error {
135
+ panic ("not implemented" )
37
136
return nil
38
137
}
0 commit comments