From 38303c53124160213317e4b6b97e59b16dc0709c Mon Sep 17 00:00:00 2001 From: jhoffner Date: Wed, 12 Jul 2017 16:16:41 -0700 Subject: [PATCH 1/5] Code Cleanup - docker images no longer use timeout as default entrypoint - ESLint fixes --- .eslintignore | 1 + docker-compose.yml | 10 +++ docker/alt.docker | 2 +- docker/chapel.docker | 2 +- docker/crystal.docker | 2 + docker/dart.docker | 2 + docker/dotnet.docker | 2 +- docker/erlang.docker | 2 +- docker/esolangs.docker | 2 +- docker/func.docker | 2 +- docker/go.docker | 2 +- docker/haskell.docker | 6 +- docker/julia.docker | 2 +- docker/jvm.docker | 2 +- docker/lua.docker | 2 +- docker/node.docker | 2 +- docker/objc.docker | 2 +- docker/ocaml.docker | 2 +- docker/python.docker | 2 +- docker/ruby.docker | 4 +- docker/rust.docker | 2 + docker/swift.docker | 2 +- docker/systems.docker | 2 +- frameworks/javascript/cw-2.js | 24 +++---- frameworks/javascript/display.js | 10 +-- lib/runners/arm.js | 2 +- lib/runners/c.js | 15 ++-- lib/runners/chapel.js | 14 ++-- lib/runners/clojure.js | 6 +- lib/runners/cpp.js | 15 ++-- lib/runners/fsharp.js | 2 +- lib/runners/gas.js | 2 +- lib/runners/haskell.js | 5 +- lib/runners/javascript.js | 13 ++-- lib/runners/lisp.js | 2 +- lib/runners/nasm.js | 2 +- lib/runners/python.js | 12 ++-- lib/runners/typescript.js | 11 +-- run.js | 120 +++++++++++++++---------------- 39 files changed, 170 insertions(+), 144 deletions(-) diff --git a/.eslintignore b/.eslintignore index d7257755..92373297 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ frameworks/javascript/angular/ +frameworks/java diff --git a/docker-compose.yml b/docker-compose.yml index 11fbd8aa..8bc28d98 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -192,6 +192,16 @@ services: entrypoint: '' command: bash + chapel-runner: + image: codewars/chapel-runner + volumes: + - ./lib:/runner/lib + - ./examples:/runner/examples + - ./frameworks:/runner/frameworks + - ./test:/runner/test + entrypoint: '' + command: bash + # LANGUAGE SPECIFIC HELPERS javascript: image: codewars/node-runner diff --git a/docker/alt.docker b/docker/alt.docker index 03d13675..e9c69c82 100644 --- a/docker/alt.docker +++ b/docker/alt.docker @@ -42,4 +42,4 @@ RUN mocha -t 3000 test/runners/php_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/chapel.docker b/docker/chapel.docker index 6e2723fa..c4803e66 100644 --- a/docker/chapel.docker +++ b/docker/chapel.docker @@ -34,4 +34,4 @@ WORKDIR /runner USER codewarrior RUN mocha -t 10000 test/runners/chapel_spec.js -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/crystal.docker b/docker/crystal.docker index a74a753e..feefbeca 100644 --- a/docker/crystal.docker +++ b/docker/crystal.docker @@ -44,3 +44,5 @@ ADD frameworks/crystal/formatter.cr /home/codewarrior/crystal/formatter.cr USER codewarrior RUN mocha -t 10000 test/runners/crystal_spec.js + +ENTRYPOINT ["node"] diff --git a/docker/dart.docker b/docker/dart.docker index d0e51c8f..b6cdd648 100644 --- a/docker/dart.docker +++ b/docker/dart.docker @@ -42,3 +42,5 @@ RUN ln -s /home/codewarrior /workspace USER codewarrior RUN mocha -t 10000 test/runners/dart_spec.js + +ENTRYPOINT ["node"] diff --git a/docker/dotnet.docker b/docker/dotnet.docker index a5aedb6c..2e28a925 100644 --- a/docker/dotnet.docker +++ b/docker/dotnet.docker @@ -57,4 +57,4 @@ RUN mono -V #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/erlang.docker b/docker/erlang.docker index ae080b3a..056233ad 100644 --- a/docker/erlang.docker +++ b/docker/erlang.docker @@ -56,4 +56,4 @@ RUN mocha -t 5000 test/runners/{erlang,elixir}_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/esolangs.docker b/docker/esolangs.docker index e660c8df..49cc3501 100644 --- a/docker/esolangs.docker +++ b/docker/esolangs.docker @@ -25,4 +25,4 @@ RUN mocha -t 10000 test/runners/bf_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/func.docker b/docker/func.docker index 2ddfef9c..cf26b158 100644 --- a/docker/func.docker +++ b/docker/func.docker @@ -34,4 +34,4 @@ RUN mocha -t 5000 test/runners/{ocaml,racket}_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/go.docker b/docker/go.docker index 88ed4865..b559541d 100644 --- a/docker/go.docker +++ b/docker/go.docker @@ -52,4 +52,4 @@ RUN mocha -t 5000 test/runners/go_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "17", "node"] +ENTRYPOINT ["node"] diff --git a/docker/haskell.docker b/docker/haskell.docker index df2b1e23..e016c564 100644 --- a/docker/haskell.docker +++ b/docker/haskell.docker @@ -28,7 +28,7 @@ RUN cabal update RUN cabal install cabal-install # Install Haskell Packages -# To install additional packages use "RUN cabal install " +# To install additional packages use "RUN cabal install " RUN cabal install split ifelse RUN cabal install persistent-sqlite persistent-template RUN cabal install haskell-src-exts lens @@ -38,7 +38,7 @@ RUN cabal install hspec hspec-core hspec-discover # Haskell stuff end. # ========================================================================= -# Add the package json first to a tmp directory and build, +# Add the package json first to a tmp directory and build, # copy over so that we dont rebuild every time USER root ADD package.json /tmp/package.json @@ -55,4 +55,4 @@ RUN mocha -t 10000 test/runners/haskell_spec.js # timeout is a fallback in case an error with node # prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/julia.docker b/docker/julia.docker index 6745a345..1d884609 100644 --- a/docker/julia.docker +++ b/docker/julia.docker @@ -51,4 +51,4 @@ RUN mocha -t 5000 test/runners/julia_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] \ No newline at end of file +ENTRYPOINT ["node"] diff --git a/docker/jvm.docker b/docker/jvm.docker index 65b70da4..b6534fbc 100644 --- a/docker/jvm.docker +++ b/docker/jvm.docker @@ -62,4 +62,4 @@ RUN mocha -t 10000 test/runners/{clojure,groovy,scala,kotlin}_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/lua.docker b/docker/lua.docker index 7a344703..1647fb53 100644 --- a/docker/lua.docker +++ b/docker/lua.docker @@ -32,4 +32,4 @@ RUN mocha -t 5000 test/runners/lua_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/node.docker b/docker/node.docker index a9733854..77e10a74 100644 --- a/docker/node.docker +++ b/docker/node.docker @@ -58,4 +58,4 @@ RUN mocha -t 10000 test/runners/typescript_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/objc.docker b/docker/objc.docker index 4485c742..a5b07e9d 100644 --- a/docker/objc.docker +++ b/docker/objc.docker @@ -149,4 +149,4 @@ RUN mocha -t 5000 test/runners/objc_spec.js # timeout is a fallback in case an error with node # prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/ocaml.docker b/docker/ocaml.docker index 2dfb9831..e26dc87c 100644 --- a/docker/ocaml.docker +++ b/docker/ocaml.docker @@ -44,4 +44,4 @@ RUN /home/codewarrior/run_ocaml.sh mocha -t 5000 test/runners/ocaml_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["/home/codewarrior/run_ocaml.sh", "timeout", "15", "node"] +ENTRYPOINT ["/home/codewarrior/run_ocaml.sh", "node"] diff --git a/docker/python.docker b/docker/python.docker index 9e3fa71f..b770d68a 100644 --- a/docker/python.docker +++ b/docker/python.docker @@ -102,4 +102,4 @@ RUN mocha -t 5000 test/runners/python_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/ruby.docker b/docker/ruby.docker index ecfb2b1b..9a68f79b 100644 --- a/docker/ruby.docker +++ b/docker/ruby.docker @@ -179,10 +179,10 @@ ENV USER codewarrior ENV HOME /home/codewarrior RUN mocha -t 5000 test/runners/ruby_spec.js -#RUN mocha -t 5000 test/runners/sql_spec.js RUN mocha -t 5000 test/runners/shell_spec.js +#RUN mocha -t 5000 test/runners/sql_spec.js RUN sh /runner/lib/cleanup.sh #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/rust.docker b/docker/rust.docker index 94deacef..850ee9dd 100644 --- a/docker/rust.docker +++ b/docker/rust.docker @@ -26,3 +26,5 @@ RUN ln -s /home/codewarrior /workspace USER codewarrior RUN mocha -t 10000 test/runners/rust_spec.js + +ENTRYPOINT ["node"] diff --git a/docker/swift.docker b/docker/swift.docker index 86728140..796bff59 100644 --- a/docker/swift.docker +++ b/docker/swift.docker @@ -73,4 +73,4 @@ RUN mocha -t 5000 test/runners/swift_spec.js # timeout is a fallback in case an error with node # prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/docker/systems.docker b/docker/systems.docker index 60e9e5be..e86799ba 100644 --- a/docker/systems.docker +++ b/docker/systems.docker @@ -60,4 +60,4 @@ RUN mocha -t 5000 test/runners/{c,cpp}_spec.js #timeout is a fallback in case an error with node #prevents it from exiting properly -ENTRYPOINT ["timeout", "15", "node"] +ENTRYPOINT ["node"] diff --git a/frameworks/javascript/cw-2.js b/frameworks/javascript/cw-2.js index 6de862e9..448990c4 100644 --- a/frameworks/javascript/cw-2.js +++ b/frameworks/javascript/cw-2.js @@ -256,18 +256,18 @@ try { // additional code is injected and line numbers will not match. trace: function(ex) { return (ex.stack || ex.toString() || '') - .toString() - // remove file names (ie: (/cli-runner/...)) - .replace(/\s\(.*\)/g, '') - // remove at [eval] statements - .replace(/(at)*( Object.)*\s*[(]?\[eval\].*(:\d*)*[)]?\n/g, '') - // remove stack trace beyond the Module information - .replace(/at Module[\w\s.:\d\n]*/g, '') - // remove at Object. - .replace(/\t*at Object.<\w*>\n/g, '') - // handleError is used to wrap top level code, so lets remove it so that it doesn't - // confuse users who won't understand why it is there. - .replace('at Object.Test.handleError', ''); + .toString() + // remove file names (ie: (/cli-runner/...)) + .replace(/\s\(.*\)/g, '') + // remove at [eval] statements + .replace(/(at)*( Object.)*\s*[(]?\[eval\].*(:\d*)*[)]?\n/g, '') + // remove stack trace beyond the Module information + .replace(/at Module[\w\s.:\d\n]*/g, '') + // remove at Object. + .replace(/\t*at Object.<\w*>\n/g, '') + // handleError is used to wrap top level code, so lets remove it so that it doesn't + // confuse users who won't understand why it is there. + .replace('at Object.Test.handleError', ''); }, pass: function() { _expect(true); diff --git a/frameworks/javascript/display.js b/frameworks/javascript/display.js index bd44c40f..69f925dc 100644 --- a/frameworks/javascript/display.js +++ b/frameworks/javascript/display.js @@ -134,11 +134,11 @@ module.exports.format = function format(obj, options) { */ module.exports.escapeHtml = function escapeHtml(html) { return String(html) - .replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>'); + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>'); }; /** diff --git a/lib/runners/arm.js b/lib/runners/arm.js index 0b52e81d..06c61ac0 100644 --- a/lib/runners/arm.js +++ b/lib/runners/arm.js @@ -13,7 +13,7 @@ module.exports.run = function run(opts, cb) { solutionFile = util.codeWriteSync('arm', opts.solution + '\n', dir, 'solution.s'), objectFile = solutionFile.replace(/\.[^\.]+$/, '.o'), armCommand = ['arm-linux-gnueabi-as', solutionFile, '-o', objectFile].join(' '), - // Check for whether we need to link against libc + // Check for whether we need to link against libc linker = opts.solution.search(/\.glob[a]?l\W+_start/) == -1 ? "arm-linux-gnueabi-gcc-4.7" : "arm-linux-gnueabi-ld", linkerCommand = [linker, objectFile, '-o', executable].join(' '); util.exec(armCommand, function() { diff --git a/lib/runners/c.js b/lib/runners/c.js index 97f12c4e..28a52865 100644 --- a/lib/runners/c.js +++ b/lib/runners/c.js @@ -36,13 +36,14 @@ module.exports.run = function run(opts, cb) { }, sanitizeStdErr: function(error) { error = error || ''; - return error.replace(/clang.*-std=c[^\s]+/g, '') - .replace(/Error: Command failed:/g, '') - .replace(/\/tmp.*(solution\.c|solution)[:0-9]*/g, '') - .replace('\n', '') - .replace(' ', ' ') - .replace(opts.setup || '', '') - .replace(opts.fixture || '', ''); + return error + .replace(/clang.*-std=c[^\s]+/g, '') + .replace(/Error: Command failed:/g, '') + .replace(/\/tmp.*(solution\.c|solution)[:0-9]*/g, '') + .replace('\n', '') + .replace(' ', ' ') + .replace(opts.setup || '', '') + .replace(opts.fixture || '', ''); } }); }; diff --git a/lib/runners/chapel.js b/lib/runners/chapel.js index 3468d02b..a1d9beb8 100644 --- a/lib/runners/chapel.js +++ b/lib/runners/chapel.js @@ -15,6 +15,7 @@ module.exports.run = function run(opts, cb) { if (opts.setup) handleSetup(opts, dir); const executable = path.join(dir, 'solution'); const solutionFile = util.codeWriteSync('chpl', opts.solution, dir, 'solution.chpl'); + compile([solutionFile, '-o', executable], function(error, stdout, stderr) { if (error) return fail(error, stdout, stderr); opts.publish('stdout', stdout); @@ -30,20 +31,23 @@ module.exports.run = function run(opts, cb) { opts.solution, opts.fixture, ].join('\n'), dir, 'solution.chpl'); + compile([solutionFile, '-o', executable], function(error, stdout, stderr) { if (error) return fail(error, stdout, stderr); opts.publish('stdout', stdout); + runCode({name: executable, args: []}); }); }, sanitizeStdErr: function(error) { error = error || ''; - return error.replace(/\/tmp.*(solution\.chpl|solution)[:0-9]*/g, '') - .replace(/Error: Command failed:/g, '') - .replace(/error: uncaught error/g, '') - .replace('\n', '') - .replace(' ', ' '); + return error + .replace(/\/tmp.*(solution\.chpl|solution)[:0-9]*/g, '') + .replace(/Error: Command failed:/g, '') + .replace(/error: uncaught error/g, '') + .replace('\n', '') + .replace(' ', ' '); } }); }; diff --git a/lib/runners/clojure.js b/lib/runners/clojure.js index 1e73758e..7ad12f63 100644 --- a/lib/runners/clojure.js +++ b/lib/runners/clojure.js @@ -21,9 +21,9 @@ module.exports.run = function run(opts, cb) { // HACK: don't know clojure well enough to fix issue within actual runner, but it is escaping line breaks when it shouldn't sanitizeStdOut: function(stdout) { return stdout - .replace(/\<:LF:\>\/g, '\n') - .replace(/\<:LF:\>\/g, '\n') - .replace(/\<:LF:\>\/g, '\n'); + .replace(/\<:LF:\>\/g, '\n') + .replace(/\<:LF:\>\/g, '\n') + .replace(/\<:LF:\>\/g, '\n'); } }); diff --git a/lib/runners/cpp.js b/lib/runners/cpp.js index 1b2d6101..2f94fd00 100644 --- a/lib/runners/cpp.js +++ b/lib/runners/cpp.js @@ -41,13 +41,14 @@ module.exports.run = function run(opts, cb) { sanitizeStdErr: function(error) { error = error || ''; - return error.replace(/clang.*-std=c[^\s]+/g, '') - .replace(/Error: Command failed:/g, '') - .replace(/\/tmp.*(solution\.cpp|solution)[:0-9]*/g, '') - .replace('\n', '') - .replace(' ', ' ') - .replace(opts.setup || '', '') - .replace(opts.fixture || '', ''); + return error + .replace(/clang.*-std=c[^\s]+/g, '') + .replace(/Error: Command failed:/g, '') + .replace(/\/tmp.*(solution\.cpp|solution)[:0-9]*/g, '') + .replace('\n', '') + .replace(' ', ' ') + .replace(opts.setup || '', '') + .replace(opts.fixture || '', ''); } }); }; diff --git a/lib/runners/fsharp.js b/lib/runners/fsharp.js index 9bc80336..157b0ab2 100644 --- a/lib/runners/fsharp.js +++ b/lib/runners/fsharp.js @@ -5,7 +5,7 @@ var shovel = require('../shovel'), csharpFrameworksPath = path.resolve(__dirname, '..', '..', 'frameworks', 'csharp'), fuchuPath = path.resolve(fsharpFrameworksPath, 'Fuchu', 'lib', 'Fuchu'), - // Fuchu references exception classes from these libs + // Fuchu references exception classes from these libs nunitAssemblies = ['nunit.core.dll', 'nunit.core.interfaces.dll', 'nunit.util.dll', 'nunit.framework.dll', 'Newtonsoft.Json.dll', 'Qualified.dll'], nunitPath = path.resolve(csharpFrameworksPath, 'nunit', 'bin'), gallioPath = path.resolve(fsharpFrameworksPath, 'Gallio', 'lib', 'NET40'), diff --git a/lib/runners/gas.js b/lib/runners/gas.js index da8204de..664cf329 100644 --- a/lib/runners/gas.js +++ b/lib/runners/gas.js @@ -13,7 +13,7 @@ module.exports.run = function(opts, cb) { solutionFile = util.codeWriteSync('gas', opts.solution + '\n', dir, 'solution.s'), objectFile = solutionFile.replace(/\.[^\.]+$/, '.o'), gasCommand = ['gcc', '-c', solutionFile, '-o', objectFile].join(' '), - // Check for whether we need to link against libc + // Check for whether we need to link against libc linker = opts.solution.search(/\.global\W+_start/) == -1 ? "gcc" : "ld", linkerCommand = [linker, objectFile, '-o', executable].join(' '); util.exec(gasCommand, function() { diff --git a/lib/runners/haskell.js b/lib/runners/haskell.js index f124c47b..31b4ad56 100644 --- a/lib/runners/haskell.js +++ b/lib/runners/haskell.js @@ -20,8 +20,9 @@ module.exports.run = function run(opts, cb) { if (opts.setup) codeWriteSync('haskell', opts.setup, haskellCodeDir); var solutionFileName = codeWriteSync('haskell', opts.solution, haskellCodeDir, "Main.hs"), fixtureFileName = solutionFileName.split('/').pop() == "Main.hs" ? - codeWriteSync('haskell', opts.fixture, haskellCodeDir) : - codeWriteSync('haskell', opts.fixture, haskellCodeDir, "Main.hs"); + codeWriteSync('haskell', opts.fixture, haskellCodeDir) : + codeWriteSync('haskell', opts.fixture, haskellCodeDir, "Main.hs"); + process.env["solutionFileName"] = solutionFileName; runCode({ diff --git a/lib/runners/javascript.js b/lib/runners/javascript.js index 0dd9b86a..7825e12d 100644 --- a/lib/runners/javascript.js +++ b/lib/runners/javascript.js @@ -40,12 +40,13 @@ module.exports.run = function run(opts, cb) { }, sanitizeStdErr: function(error) { error = error || ''; - return error.replace(/(\()?\/codewars\/[(\w\/-\d.js:) ;]*/g, '') - .replace(/( Object. )?[\(]?\[eval\][-:\w\d\)]* at/g, '') - .replace(/Module._compile.*/g, '') - .replace('Object.Test.handleError ', '') - .replace(opts.setup || '', '') - .replace(opts.fixture || '', ''); + return error + .replace(/(\()?\/codewars\/[(\w\/-\d.js:) ;]*/g, '') + .replace(/( Object. )?[\(]?\[eval\][-:\w\d\)]* at/g, '') + .replace(/Module._compile.*/g, '') + .replace('Object.Test.handleError ', '') + .replace(opts.setup || '', '') + .replace(opts.fixture || '', ''); }, sanitizeStdOut: function(stdout) { return this.sanitizeStdErr(stdout); diff --git a/lib/runners/lisp.js b/lib/runners/lisp.js index 59b64020..40664a4f 100644 --- a/lib/runners/lisp.js +++ b/lib/runners/lisp.js @@ -7,7 +7,7 @@ module.exports.run = function run(opts, cb) { var lispCodeDir = temp.mkdirSync('lisp'), args = [ '--noinform', // Disable banner - '--disable-ldb', // Disable the low-level debugger + '--disable-ldb', // Disable the low-level debugger '--lose-on-corruption', // Don't try to recover '--non-interactive' // No REPL ]; diff --git a/lib/runners/nasm.js b/lib/runners/nasm.js index 70f600b8..0d1a4150 100644 --- a/lib/runners/nasm.js +++ b/lib/runners/nasm.js @@ -14,7 +14,7 @@ module.exports.run = function run(opts, cb) { solutionFile = util.codeWriteSync('nasm', opts.solution + '\n', dir, 'solution.asm'), nasmCommand = ['nasm', '-felf64', solutionFile].join(' '), objectFile = solutionFile.replace(/\.[^\.]+$/, '.o'), - // Check for whether we need to link against libc + // Check for whether we need to link against libc linker = opts.solution.search(/global\W+_start/) == -1 ? "gcc" : "ld", linkerCommand = [linker, objectFile, '-o', executable].join(' '); util.exec(nasmCommand, function() { diff --git a/lib/runners/python.js b/lib/runners/python.js index 57e219a8..3592dd87 100644 --- a/lib/runners/python.js +++ b/lib/runners/python.js @@ -27,10 +27,10 @@ module.exports.run = function run(opts, cb) { // get rid of some of the noisy content. We remove line numbers since // they don't match up to what the user sees and will only confuse them. return err - .replace(/>\n\n+\n<') - .replace(/File "()?", line \d*,/g, '') - .replace(' (most recent call last)', '') - .replace(' in in ', ' in '); + .replace(/>\n\n+\n<') + .replace(/File "()?", line \d*,/g, '') + .replace(' (most recent call last)', '') + .replace(' in in ', ' in '); } }); }; @@ -100,8 +100,8 @@ function unittestCode(opts) { function pythonExec(opts, file) { file = file || opts.entryPath; return isPython3(opts) ? - `exec(compile(open("${file}", "rb").read(), "${file}", 'exec'))` : - `execfile('${file}')`; + `exec(compile(open("${file}", "rb").read(), "${file}", 'exec'))` : + `execfile('${file}')`; } function defaultImports(opts) { diff --git a/lib/runners/typescript.js b/lib/runners/typescript.js index d9ab44c3..3345992b 100644 --- a/lib/runners/typescript.js +++ b/lib/runners/typescript.js @@ -36,11 +36,12 @@ module.exports.run = function run(opts, cb) { }, sanitizeStdErr: function(error) { error = error || ''; - return error.replace(/(\()?\/codewars\/[(\w\/-\d.js:) ;]*/g, '') - .replace(/( Object. )?[\(]?\[eval\][-:\w\d\)]* at/g, '') - .replace(/Module._compile.*/g, '') - .replace('Object.Test.handleError ', '') - .replace(' ', ' '); + return error + .replace(/(\()?\/codewars\/[(\w\/-\d.js:) ;]*/g, '') + .replace(/( Object. )?[\(]?\[eval\][-:\w\d\)]* at/g, '') + .replace(/Module._compile.*/g, '') + .replace('Object.Test.handleError ', '') + .replace(' ', ' '); }, sanitizeStdOut: function(stdout) { return this.sanitizeStdErr(stdout); diff --git a/run.js b/run.js index 7a82f200..9f8e161a 100644 --- a/run.js +++ b/run.js @@ -1,66 +1,66 @@ var run = require('./lib/runner').run, opts = require("nomnom") - .options({ - code: { - abbr: 'c', - help: 'code to run' - }, - fixture: { - abbr: 'f', - help: 'Test fixture code to test with' - }, - setup: { - abbr: 's', - help: 'Setup code to be used for executing the code' - }, - language: { - abbr: 'l', - help: 'The language to execute the code in' - }, - languageVersion: { - abbr: 'lv', - help: 'The language version that should be used' - }, - testFramework: { - abbr: 't', - full: 'test-framework', - help: 'The language specific framework to run in' - }, - shell: { - abbr: 'sh', - help: 'An optional shell script which will be ran within the sandbox environment before the code is executed' - }, - timeout: { - help: 'The timeout to be used for running the code. If not specified a language specific default will be used' - }, - format: { - help: 'The output format that will be returned. Options are "default" and "json"', - default: 'default', - choices: ['default', 'json'], - abbr: 'fmt' - }, - services: { - abbr: 'srv', - help: 'Enable a set of services, such as redis or mongodb. Multiple options can be specified', - list: true, - choices: ['mongodb', 'redis'] - }, - debug: { - abbr: 'd', - help: 'Print debugging info', - flag: true - }, - version: { - abbr: 'v', - flag: true, - help: 'Print version and exit', - callback: function() { - return require('./lib/config').version; - } + .options({ + code: { + abbr: 'c', + help: 'code to run' + }, + fixture: { + abbr: 'f', + help: 'Test fixture code to test with' + }, + setup: { + abbr: 's', + help: 'Setup code to be used for executing the code' + }, + language: { + abbr: 'l', + help: 'The language to execute the code in' + }, + languageVersion: { + abbr: 'lv', + help: 'The language version that should be used' + }, + testFramework: { + abbr: 't', + full: 'test-framework', + help: 'The language specific framework to run in' + }, + shell: { + abbr: 'sh', + help: 'An optional shell script which will be ran within the sandbox environment before the code is executed' + }, + timeout: { + help: 'The timeout to be used for running the code. If not specified a language specific default will be used' + }, + format: { + help: 'The output format that will be returned. Options are "default" and "json"', + default: 'default', + choices: ['default', 'json'], + abbr: 'fmt' + }, + services: { + abbr: 'srv', + help: 'Enable a set of services, such as redis or mongodb. Multiple options can be specified', + list: true, + choices: ['mongodb', 'redis'] + }, + debug: { + abbr: 'd', + help: 'Print debugging info', + flag: true + }, + version: { + abbr: 'v', + flag: true, + help: 'Print version and exit', + callback: function() { + return require('./lib/config').version; } - }) - .help('This utility will run code in a specified language, using the specified testing suite.') - .parse(); + } + }) + .help('This utility will run code in a specified language, using the specified testing suite.') + .parse(); run(opts); From 2c97cf2b96011f2d01dab304b5aa8ed34abbe36f Mon Sep 17 00:00:00 2001 From: jhoffner Date: Wed, 12 Jul 2017 22:05:18 -0700 Subject: [PATCH 2/5] Listen/Readme - listen.js no longer fails - updated Readme to include BF and Chapel --- README.md | 8 +++++--- docker-compose.yml | 10 ++++++++++ listen.js | 8 ++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0b552120..dba8a305 100644 --- a/README.md +++ b/README.md @@ -73,18 +73,20 @@ Many languages are currently supported in various states of completeness. This l | Language | Version | Basic Run | Project Mode | Test Integration | Codewars | Qualified | Docker Image | Examples | Notes | |----------------|---------------|------------|--------------|------------------|----------------|----------------|--------------|---------------| ------------------------------------------------------------------------| | Assembly (GAS) | | !!! | | | | | systems-runner | | Travis is failing, tests pass locally | -| Bash | | ✓ | ✓ | | Kumite Only | | * | | | +| Bash | | ✓ | ✓ | rspec | rspec | rspec | ruby-runner | | | +| Brainf**k | 20041219 | ✓ | ✓ | cw-2 | cw-2 | | esolangs-runner | | | | C | Clang 3.6/C11 | ✓ | | criterion | criterion | | systems-runner | | | | Clojure | 1.6.0 | ✓ | | clojure.test | clojure.test | clojure.test | jvm-runner | clojure.test | | | CoffeeScript | 1.10.0 | ✓ | | cw-2 | cw-2 | cw-2 | node-runner | cw-2 | | -| C++ | 14 | ✓ | | igloo | igloo | | systems-runner | | | +| C++ | 14 | ✓ | | igloo | igloo | igloo | systems-runner | | | | C# | Mono 4.8 | ✓ | ✓ | nunit | nunit | nunit | dotnet-runner | nunit | | +| Chapel | 1.15.0 | ✓ | ✓ | cw-2 | cw-2 | | chapel-runner | cw-2 | | | Crystal | 0.21.1 | ✓ | | spec | spec | spec | crystal-runner | spec | | | Dart | 1.16.1 | ✓ | | test | Kumite Only | | dart-runner | test | | | Elixir | 1.2.4 | ✓ | | exunit | exunit | | erlang-runner | | | | Erlang | 18 | ✓ | | | | | erlang-runner | | | | F# | 4.1 | ✓ | | fuchu | fuchu | | dotnet-runner | Fuchu | Tests should be placed in a module called "Tests", in a Fuchu testList | -| Go | 1.8 | ✓ | | ginkgo | ginkgo | | go-runner | ginkgo | | +| Go | 1.8 | ✓ | | ginkgo | ginkgo | ginkgo | go-runner | ginkgo | | | Groovy | | ✓ | | | Kumite Only | | jvm-runner | | | | Haskell | 7.6.3 | ✓ | | hspec!!! | hspec | hspec | haskell-runner | hspec | An older version is running on CW & Qualified that is fully functional | | Java | 1.8.0_91 | ✓ | | junit | Yes | Yes | jvm-runner | junit | | diff --git a/docker-compose.yml b/docker-compose.yml index 8bc28d98..96e3ce79 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -202,6 +202,16 @@ services: entrypoint: '' command: bash + esolangs-runner: + image: codewars/esolangs-runner + volumes: + - ./lib:/runner/lib + - ./examples:/runner/examples + - ./frameworks:/runner/frameworks + - ./test:/runner/test + entrypoint: '' + command: bash + # LANGUAGE SPECIFIC HELPERS javascript: image: codewars/node-runner diff --git a/listen.js b/listen.js index dae50ccd..3268d907 100644 --- a/listen.js +++ b/listen.js @@ -1,9 +1,13 @@ // this file is used to keep a image alive so that it can be pre-warmed and communicated with. const net = require('net'), - execSync = require('child_process').execSync; + execSync = require('child_process').execSync, + fs = require('fs'); // if the script is available, it will call it -console.log(execSync('sh /runner/prewarm.sh').toString()); +if (fs.existsSync('/runner/prewarm.sh')) { + console.log(execSync('sh /runner/prewarm.sh').toString()); +} + // Creates a new TCP server. The handler argument is automatically set as a listener for the 'connection' event var server = net.createServer(function(socket) { From 26e1b350ab61c930fe9f26c36112224a1c595c72 Mon Sep 17 00:00:00 2001 From: jhoffner Date: Fri, 14 Jul 2017 12:56:58 -0700 Subject: [PATCH 3/5] Ruby/BF/Chapel Updates - Ruby now has bcrypt gem, for better Rails integration - BF now supports setup code - Chapel setup code was reworked to not use mutation --- docker/ruby.docker | 4 +--- lib/runners/bf.js | 1 + lib/runners/chapel.js | 8 ++------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docker/ruby.docker b/docker/ruby.docker index 9a68f79b..f1ae454f 100644 --- a/docker/ruby.docker +++ b/docker/ruby.docker @@ -129,11 +129,9 @@ RUN gem install statsample-timeseries --no-ri --no-rdoc RUN gem install stuff-classifier --no-ri --no-rdoc RUN gem install symbolic --no-ri --no-rdoc RUN gem install unit --no-ri --no-rdoc - RUN gem install chronic --no-ri --no-rdoc - -# partner packages RUN gem install ably --no-ri --no-rdoc +RUN gem install bcrypt --no-ri --no-rdoc USER codewarrior diff --git a/lib/runners/bf.js b/lib/runners/bf.js index 933a9952..53a11fa0 100644 --- a/lib/runners/bf.js +++ b/lib/runners/bf.js @@ -15,6 +15,7 @@ module.exports.run = function run(opts, cb) { case 'cw-2': var fixture = ` require('/runner/frameworks/javascript/cw-2'); +${opts.setup}; const runBF = require('/runner/frameworks/bf/run-bf.js'); ${opts.fixture}; `; diff --git a/lib/runners/chapel.js b/lib/runners/chapel.js index a1d9beb8..5bc6481f 100644 --- a/lib/runners/chapel.js +++ b/lib/runners/chapel.js @@ -12,7 +12,7 @@ module.exports.run = function run(opts, cb) { const dir = temp.mkdirSync('chpl'); shovel.start(opts, cb, { solutionOnly: function(runCode, fail) { - if (opts.setup) handleSetup(opts, dir); + const code = [opts.setup, opts.solution].filter(l => !!l).join("\n"); const executable = path.join(dir, 'solution'); const solutionFile = util.codeWriteSync('chpl', opts.solution, dir, 'solution.chpl'); @@ -24,10 +24,10 @@ module.exports.run = function run(opts, cb) { }, testIntegration: function(runCode, fail) { - if (opts.setup) handleSetup(opts, dir); const executable = path.join(dir, 'solution'); const solutionFile = util.codeWriteSync('chpl', [ cw2, + opts.setup, opts.solution, opts.fixture, ].join('\n'), dir, 'solution.chpl'); @@ -56,7 +56,3 @@ module.exports.run = function run(opts, cb) { function compile(args, cb) { exec(`chpl ${args.join(' ')}`, cb); } - -function handleSetup(opts, dir) { - opts.solution = opts.setup + '\n' + opts.solution; -} From a011e7f56c77e1fd81cc172e69157a014e8b5381 Mon Sep 17 00:00:00 2001 From: jhoffner Date: Fri, 14 Jul 2017 14:19:00 -0700 Subject: [PATCH 4/5] Fixed bad reference issue --- lib/runners/chapel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runners/chapel.js b/lib/runners/chapel.js index 5bc6481f..6a932236 100644 --- a/lib/runners/chapel.js +++ b/lib/runners/chapel.js @@ -14,7 +14,7 @@ module.exports.run = function run(opts, cb) { solutionOnly: function(runCode, fail) { const code = [opts.setup, opts.solution].filter(l => !!l).join("\n"); const executable = path.join(dir, 'solution'); - const solutionFile = util.codeWriteSync('chpl', opts.solution, dir, 'solution.chpl'); + const solutionFile = util.codeWriteSync('chpl', code, dir, 'solution.chpl'); compile([solutionFile, '-o', executable], function(error, stdout, stderr) { if (error) return fail(error, stdout, stderr); From e2388c1fda747eb6ef5c6abb6a70ce6cbb09b48a Mon Sep 17 00:00:00 2001 From: jhoffner Date: Fri, 14 Jul 2017 15:49:18 -0700 Subject: [PATCH 5/5] Java Compiler Warnings - Compiler warnings have been moved into Build Output --- lib/runners/java.js | 21 +++++++++++++++++---- test/runners/java_spec.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/runners/java.js b/lib/runners/java.js index 44be76eb..275bb8bf 100644 --- a/lib/runners/java.js +++ b/lib/runners/java.js @@ -75,17 +75,30 @@ module.exports.run = function run(opts, cb) { } }); + buffer.stderr += stderr; + // let's not show the noisy "Try:" text when there are build errors + buffer.stderr = buffer.stderr.split(/\^* Try:/m)[0]; + // attach build output to beginning of stdout, also attach dependencies so everyone knows whats available // TODO: eventually we want to support this as its own buffer property, for now we are just embedding it // within the output in case its helpful for troubleshooting let buildOutput = `Dependencies:\n\n${loadedDependencies()}\n\nTasks:\n\n`; buildOutput += buildLines.join("\n").replace(/^Start > start.*/gm, ''); + + // lets strip out any STDERR compiler warnings and and save them for later + const notes = []; + buffer.stderr = buffer.stderr.replace(/^Note:.*\n/gm, function(t) { + notes.push(t); + return ''; + }); + + // now lets move those warnings to the build output + if (notes.length) { + buildOutput += `\n\nCompiler Warnings:\n\n${notes.join("\n")}`; + } + buildOutput = tagHelpers.log('-Build Output', buildOutput); buffer.stdout = buildOutput + stdout; - - buffer.stderr += stderr; - // let's not show the noisy "Try:" text when there are build errors - buffer.stderr = buffer.stderr.split(/\^* Try:/m)[0]; } }); diff --git a/test/runners/java_spec.js b/test/runners/java_spec.js index a8f42de3..888f6912 100644 --- a/test/runners/java_spec.js +++ b/test/runners/java_spec.js @@ -249,6 +249,40 @@ describe('java runner', function() { }); }); + describe('compiler warnings as STDERR messages', function() { + it('should handle unchecked or unsafe operations', function(done) { + runner.run({ + language: 'java', + code: ` + import java.util.ArrayList; + + public class Example { + + public static String[] dirReduc(String[] arr) { + ArrayList result = new ArrayList(); + return result.toArray(new String[result.size()]); + } + } + `, + fixture: ` + import org.junit.Test; + import static org.junit.Assert.assertEquals; + + public class ExampleTest { + @Test + public void testRandomDirReduc() throws Exception { + assertEquals("I always pass!", 1, 1); + } + }` + }, function(buffer) { + console.log(`|${buffer.stderr}|`); + expect(buffer.stderr).to.equal(''); + done(); + }); + + }); + }); + describe('spring', function() { it('should handle basic junit tests', function(done) { runner.run({