17
17
from SocketServer import ThreadingMixIn
18
18
from BaseHTTPServer import HTTPServer
19
19
20
+ ALLOW_CACHE = True
20
21
PORT = 11111
21
22
TEST_SERVERS = False
22
23
TMP_DIR = "tmp/"
@@ -81,6 +82,8 @@ class Program {
81
82
}
82
83
""" ,
83
84
"cmd" : "csc Program.cs StdLib.cs > /dev/null && ./Program.exe" ,
85
+ "compileCmd" : "csc -recurse:src/*.cs -out:bin/Program.exe" ,
86
+ "runCmd" : "mono Program.exe" ,
84
87
"mainFn" : "Program.cs" ,
85
88
"stdlibFn" : "StdLib.cs" ,
86
89
"versionCmd" : "dotnet --info; echo CSC version: `csc -version`" ,
@@ -99,7 +102,7 @@ class Program {
99
102
"ext" : "cpp" ,
100
103
"mainFn" : "main.cpp" ,
101
104
"stdlibFn" : "one.hpp" ,
102
- "cmd" : "g++ -std=c++17 main.cpp -I. -o binary && ./binary" ,
105
+ "cmd" : "g++ -std=c++17 main.cpp one_packages/*/*.cpp -I. -Ione_packages -o binary && ./binary" ,
103
106
"versionCmd" : "g++ -v" ,
104
107
},
105
108
"go" : {
@@ -120,7 +123,7 @@ class Program {
120
123
"ext" : "swift" ,
121
124
"mainFn" : "main.swift" ,
122
125
"stdlibFn" : "one.swift" ,
123
- "cmd" : "cat one.swift main.swift | swift -" ,
126
+ "cmd" : "cat main.swift | swift -" ,
124
127
"versionCmd" : "swift --version" ,
125
128
}
126
129
}
@@ -210,7 +213,7 @@ def log_message(self, format, *args):
210
213
pass
211
214
212
215
def resp (self , statusCode , result ):
213
- result ["controllerVersion" ] = "one:v1:20180122 "
216
+ result ["controllerVersion" ] = "one:v2:20200218 "
214
217
responseBody = json .dumps (result )
215
218
self .send_response (statusCode )
216
219
self .send_header ("Content-Length" , "%d" % len (responseBody ))
@@ -229,50 +232,72 @@ def end_headers(self):
229
232
def api_compile (self ):
230
233
requestJson = self .rfile .read (int (self .headers .getheader ('content-length' )))
231
234
useCache = self .queryParams .get ("useCache" )
232
- if useCache :
235
+ if ALLOW_CACHE :
233
236
requestHash = hashlib .sha256 (requestJson ).hexdigest ()[0 :12 ]
234
237
cacheFn = "%s/compilecache_%s_resp.json" % (TMP_DIR , requestHash )
235
- if os .path .exists (cacheFn ):
238
+ if useCache and os .path .exists (cacheFn ):
236
239
with open (cacheFn , "rt" ) as f :
237
240
response = json .loads (f .read ())
238
241
response ["fromCache" ] = True
242
+ response ["cacheId" ] = requestHash
239
243
self .resp (200 , response )
240
244
return
241
245
242
246
request = json .loads (requestJson )
243
247
request ["cmd" ] = "compile"
244
248
langName = request ["lang" ]
249
+ mode = request ["mode" ] if "mode" in request else "auto"
245
250
lang = LANGS [langName ]
246
251
247
252
start = time .time ()
248
- if "jsonRepl" in lang :
253
+ if mode == "jsonRepl" or ( mode == "auto" and "jsonRepl" in lang ) :
249
254
response = lang ["jsonRepl" ].request (request )
250
- elif "server" in lang :
255
+ elif mode == "server" or ( mode == "auto" and "server" in lang ) :
251
256
responseJson = postRequest ("http://127.0.0.1:%d" % lang ["port" ], requestJson )
252
257
response = json .loads (responseJson )
253
- else :
254
- dateStr = datetime .datetime .now ().strftime ("%Y%m%d_%H%M%S" )
255
- outDir = "%s%s_%s/" % (TMP_DIR , dateStr , langName )
256
-
257
- with open (providePath (outDir + lang ["mainFn" ]), "wt" ) as f : f .write (request ["code" ])
258
-
259
- if "stdlibCode" in request :
260
- with open (providePath (outDir + lang ["stdlibFn" ]), "wt" ) as f : f .write (request ["stdlibCode" ])
261
-
262
- for pkgSrc in request ["packageSources" ]:
263
- with open (providePath (outDir + pkgSrc ["fileName" ]), "wt" ) as f : f .write (pkgSrc ["code" ])
258
+ elif mode == "native" or mode == "auto" :
259
+ dateStr = datetime .datetime .now ().strftime ("%Y%m%d_%H%M%S_%f" )
260
+ dirName = "%s_%s" % (dateStr , langName )
261
+ if "name" in request :
262
+ dirName += "_" + request ["name" ]
263
+ outDir = "%s%s/" % (TMP_DIR , dirName )
264
+ binDir = outDir + "/bin/"
265
+ mkdir_p (binDir )
266
+
267
+ response = { "tmpDir" : dirName , "success" : False }
268
+
269
+ for (filename , code ) in request ["files" ].items ():
270
+ with open (providePath (outDir + "src/" + filename ), "wt" ) as f : f .write (code )
271
+
272
+ #with open(providePath(outDir + lang["mainFn"]), "wt") as f: f.write(request["code"])
273
+ #if "stdlibCode" in request:
274
+ # with open(providePath(outDir + lang["stdlibFn"]), "wt") as f: f.write(request["stdlibCode"])
275
+ #for pkgSrc in request["packageSources"]:
276
+ # with open(providePath(outDir + "one_packages/" + pkgSrc["packageName"] + "/" + pkgSrc["fileName"]), "wt") as f: f.write(pkgSrc["code"])
264
277
265
- pipes = subprocess .Popen (lang ["cmd " ], shell = True , cwd = outDir , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
278
+ pipes = subprocess .Popen (lang ["compileCmd " ], shell = True , cwd = outDir , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
266
279
stdout , stderr = pipes .communicate ()
280
+ success = pipes .returncode == 0 and stderr == ""
281
+ response ["compilation" ] = { "stdout" : stdout , "stderr" : stderr , "exitCode" : pipes .returncode , "success" : success }
267
282
268
- response = { "result" : stdout }
269
-
270
- if pipes .returncode != 0 or len (stderr ) > 0 :
271
- response ["exceptionText" ] = stderr
283
+ if not success :
284
+ response ["error" ] = "Program run failed with exitCode %d\n Stderr:\n %s\n Stdout:\n %s" % (pipes .returncode , stderr , stdout )
272
285
else :
273
- shutil .rmtree (outDir )
286
+ pipes = subprocess .Popen (lang ["runCmd" ], shell = True , cwd = binDir , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
287
+ stdout , stderr = pipes .communicate ()
288
+ success = pipes .returncode == 0 and stderr == ""
289
+ response ["run" ] = { "stdout" : stdout , "stderr" : stderr , "exitCode" : pipes .returncode , "success" : success }
290
+
291
+ if not success :
292
+ response ["error" ] = "Program run failed with exitCode %d\n Stderr:\n %s\n Stdout:\n %s" % (pipes .returncode , stderr , stdout )
293
+ else :
294
+ response ["success" ] = True
295
+ shutil .rmtree (outDir )
296
+ else :
297
+ response = { "error" : "Unknown mode '%s'" % mode , "success" : False }
274
298
275
- if useCache :
299
+ # cache should be overwritten even when useCache is False, otherwise a broken version stays there forever
300
+ if ALLOW_CACHE :
276
301
with open (cacheFn , "wt" ) as f : f .write (json .dumps (response ))
277
302
278
303
response ["elapsedMs" ] = int ((time .time () - start ) * 1000 )
0 commit comments