forked from SOMAS2020/SOMAS2020
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
175 lines (152 loc) · 4.1 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// +build !js
// Package main is the main entrypoint of the program.
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
"os"
"path"
"runtime"
"time"
"github.com/SOMAS2020/SOMAS2020/internal/server"
"github.com/SOMAS2020/SOMAS2020/pkg/fileutils"
"github.com/SOMAS2020/SOMAS2020/pkg/gitinfo"
"github.com/SOMAS2020/SOMAS2020/pkg/logger"
"github.com/pkg/errors"
)
const outputJSONFileName = "output.json"
const outputLogFileName = "log.txt"
// non-WASM flags.
// see `params.go` for shared flags.
var (
outputFolderName = flag.String(
"output",
"output",
"The relative path (to the current working directory) to store output.json and logs in.\n"+
"WARNING: This folder will be removed prior to running!",
)
logLevel = flag.Uint(
"logLevel",
1,
"Logging verbosity level. Note that output artifacts will remain the same.\n"+
"0: No logs at all\n"+
"1: Logs in logs.txt\n"+
"2: 1 + logs to stderr\n"+
"3: 2 + game states to stdout\n",
)
)
func main() {
timeStart := time.Now()
rand.Seed(timeStart.UTC().UnixNano())
flag.Parse()
var err error
wd, err := os.Getwd()
if err != nil {
log.Fatalf("%v", err)
}
absOutputDir := path.Join(wd, *outputFolderName)
err = prepareOutputFolder(absOutputDir)
if err != nil {
log.Fatalf("Failed to prepare output folder: %v", err)
}
err = prepareLogger(absOutputDir)
if err != nil {
log.Fatalf("Failed to prepare logger: %v", err)
}
gameConfig, err := parseConfig()
if err != nil {
log.Fatalf("Flag parse error: %v\nUse --help.", err)
}
s, err := server.NewSOMASServer(gameConfig)
if err != nil {
log.Fatalf("Failed to initial SOMASServer: %v", err)
}
if gameStates, err := s.EntryPoint(); err != nil {
log.Fatalf("Run failed with: %+v", err)
} else {
if *logLevel >= 3 {
fmt.Printf("===== GAME CONFIGURATION =====\n")
fmt.Printf("%#v\n", gameConfig)
for _, st := range gameStates {
fmt.Printf("===== START OF TURN %v (END OF TURN %v) =====\n", st.Turn, st.Turn-1)
fmt.Printf("%#v\n", st)
}
}
timeEnd := time.Now()
err = outputJSON(output{
GameStates: gameStates,
Config: gameConfig,
GitInfo: getGitInfo(),
AuxInfo: getAuxInfo(),
RunInfo: runInfo{
TimeStart: timeStart,
TimeEnd: timeEnd,
DurationSeconds: timeEnd.Sub(timeStart).Seconds(),
Version: runtime.Version(),
GOOS: runtime.GOOS,
GOARCH: runtime.GOARCH,
},
}, absOutputDir)
if err != nil {
log.Fatalf("Failed to output JSON: %v", err)
}
}
}
func prepareOutputFolder(absOutputDir string) error {
// cleanup output
err := fileutils.RemovePathIfExists(absOutputDir)
if err != nil {
return err
}
// make output directory
err = os.Mkdir(absOutputDir, 0777)
if err != nil {
return err
}
return nil
}
func prepareLogger(absOutputDir string) error {
writers := []io.Writer{}
if *logLevel >= 1 {
outputLogFilePath := path.Join(absOutputDir, outputLogFileName)
f, err := os.OpenFile(outputLogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0777)
if err != nil {
return errors.Errorf("Unable to open log file, try running using sudo: %v", err)
}
writers = append(writers, f)
}
if *logLevel >= 2 {
writers = append(writers, os.Stderr)
}
log.SetOutput(
logger.NewLogWriter(writers),
)
return nil
}
func outputJSON(o output, absOutputDir string) error {
outputJSONFilePath := path.Join(absOutputDir, outputJSONFileName)
log.Printf("Writing JSON output to '%v'\n", outputJSONFilePath)
jsonBuf, err := json.MarshalIndent(o, "", "\t")
if err != nil {
return errors.Errorf("Failed to Marshal gameStates: %v", err)
}
err = ioutil.WriteFile(outputJSONFilePath, jsonBuf, 0777)
if err != nil {
return errors.Errorf("Failed to write file: %v", err)
}
log.Printf("Finished writing JSON output to '%v'", outputJSONFilePath)
return nil
}
func getGitInfo() gitinfo.GitInfo {
repoRootPath := fileutils.GetCurrFileDir()
gitInfo, err := gitinfo.GetGitInfo(repoRootPath)
if err != nil {
log.Printf("Ignoring error in getting git info--are you running this in a valid git repo? Error: %v", err)
}
return gitInfo
}