From 765ceeaa7b8e7a2cfa6957610f827eece0c02613 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sun, 27 Oct 2024 08:01:10 +0000 Subject: [PATCH 1/8] Move code into source/server --- .dockerignore | 2 +- Dockerfile | 13 +-- client/Dockerfile | 7 +- docker-compose.yml | 6 +- .../server}/capture3_with_timeout.rb | 0 {code => source/server}/config/config.ru | 0 {code => source/server}/config/healthcheck.sh | 0 {code => source/server}/config/puma.rb | 0 {code => source/server}/config/up.sh | 0 {code => source/server}/context.rb | 0 {code => source/server}/dispatcher.rb | 0 {code => source/server}/empty_binding.rb | 0 .../externals/asynchronous_threader.rb | 0 .../server}/externals/bash_sheller.rb | 0 .../server}/externals/pipe_maker.rb | 0 .../server}/externals/process_spawner.rb | 0 {code => source/server}/externals/random.rb | 0 .../server}/externals/stdout_logger.rb | 0 {code => source/server}/files_delta.rb | 0 {code => source/server}/gnu_unzip.rb | 0 {code => source/server}/gnu_zip.rb | 0 {code => source/server}/home_files.rb | 0 {code => source/server}/node.rb | 0 {code => source/server}/prober.rb | 0 {code => source/server}/puller.rb | 0 {code => source/server}/rack_dispatcher.rb | 0 {code => source/server}/rag_lambdas.rb | 0 {code => source/server}/runner.rb | 0 {code => source/server}/sandbox.rb | 0 {code => source/server}/synchronized_set.rb | 0 {code => source/server}/tagged_image_name.rb | 0 {code => source/server}/tarfile_reader.rb | 0 {code => source/server}/tarfile_writer.rb | 0 {code => source/server}/tgz.rb | 0 {code => source/server}/traffic_light.rb | 0 {code => source/server}/utf8_clean.rb | 0 .../languages_start_points.manifests.json | 92 +++++++++---------- test/lib/coverage.rb | 11 ++- test/require_code.rb | 2 +- test/server/traffic_light_test.rb | 2 +- 40 files changed, 63 insertions(+), 72 deletions(-) rename {code => source/server}/capture3_with_timeout.rb (100%) rename {code => source/server}/config/config.ru (100%) rename {code => source/server}/config/healthcheck.sh (100%) rename {code => source/server}/config/puma.rb (100%) rename {code => source/server}/config/up.sh (100%) rename {code => source/server}/context.rb (100%) rename {code => source/server}/dispatcher.rb (100%) rename {code => source/server}/empty_binding.rb (100%) rename {code => source/server}/externals/asynchronous_threader.rb (100%) rename {code => source/server}/externals/bash_sheller.rb (100%) rename {code => source/server}/externals/pipe_maker.rb (100%) rename {code => source/server}/externals/process_spawner.rb (100%) rename {code => source/server}/externals/random.rb (100%) rename {code => source/server}/externals/stdout_logger.rb (100%) rename {code => source/server}/files_delta.rb (100%) rename {code => source/server}/gnu_unzip.rb (100%) rename {code => source/server}/gnu_zip.rb (100%) rename {code => source/server}/home_files.rb (100%) rename {code => source/server}/node.rb (100%) rename {code => source/server}/prober.rb (100%) rename {code => source/server}/puller.rb (100%) rename {code => source/server}/rack_dispatcher.rb (100%) rename {code => source/server}/rag_lambdas.rb (100%) rename {code => source/server}/runner.rb (100%) rename {code => source/server}/sandbox.rb (100%) rename {code => source/server}/synchronized_set.rb (100%) rename {code => source/server}/tagged_image_name.rb (100%) rename {code => source/server}/tarfile_reader.rb (100%) rename {code => source/server}/tarfile_writer.rb (100%) rename {code => source/server}/tgz.rb (100%) rename {code => source/server}/traffic_light.rb (100%) rename {code => source/server}/utf8_clean.rb (100%) diff --git a/.dockerignore b/.dockerignore index 33a36ea5..bbce0851 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,2 @@ * -!code/ +!source/server/ diff --git a/Dockerfile b/Dockerfile index abf542db..0e6e9f3a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,15 @@ -ARG BASE_IMAGE=cyberdojo/docker-base:43587ec -FROM ${BASE_IMAGE} -# ARGs are reset after FROM See https://github.com/moby/moby/issues/34129 -ARG BASE_IMAGE -ENV BASE_IMAGE=${BASE_IMAGE} - +FROM cyberdojo/docker-base:43587ec LABEL maintainer=jon@jaggersoft.com RUN gem install --no-document 'concurrent-ruby' WORKDIR /runner -COPY . . +COPY source/server/ . ARG COMMIT_SHA ENV SHA=${COMMIT_SHA} USER root -HEALTHCHECK --interval=1s --timeout=1s --retries=5 --start-period=5s CMD /runner/code/config/healthcheck.sh +HEALTHCHECK --interval=1s --timeout=1s --retries=5 --start-period=5s CMD /runner/config/healthcheck.sh ENTRYPOINT ["/sbin/tini", "-g", "--"] -CMD [ "/runner/code/config/up.sh" ] +CMD [ "/runner/config/up.sh" ] diff --git a/client/Dockerfile b/client/Dockerfile index 3880c542..ed9088fb 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,9 +1,4 @@ -ARG BASE_IMAGE=cyberdojo/docker-base:43587ec -FROM ${BASE_IMAGE} -# ARGs are reset after FROM See https://github.com/moby/moby/issues/34129 -ARG BASE_IMAGE -ENV BASE_IMAGE=${BASE_IMAGE} - +FROM cyberdojo/docker-base:43587ec LABEL maintainer=jon@jaggersoft.com WORKDIR /runner diff --git a/docker-compose.yml b/docker-compose.yml index f1fd0bd9..1caa4990 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: env_file: [ .env ] environment: [ CONTEXT=client, SHOW_TEST_IDS ] read_only: true - restart: 'no' + restart: no tmpfs: /tmp volumes: - ./test:/runner/test/:ro @@ -30,7 +30,7 @@ services: env_file: [ .env ] environment: [ CONTEXT=server, SHOW_TEST_IDS ] read_only: true - restart: 'no' + restart: no tmpfs: /tmp volumes: - ./test:/runner/test/:ro @@ -41,5 +41,5 @@ services: user: nobody env_file: [ .env ] read_only: true - restart: "no" + restart: no tmpfs: /tmp diff --git a/code/capture3_with_timeout.rb b/source/server/capture3_with_timeout.rb similarity index 100% rename from code/capture3_with_timeout.rb rename to source/server/capture3_with_timeout.rb diff --git a/code/config/config.ru b/source/server/config/config.ru similarity index 100% rename from code/config/config.ru rename to source/server/config/config.ru diff --git a/code/config/healthcheck.sh b/source/server/config/healthcheck.sh similarity index 100% rename from code/config/healthcheck.sh rename to source/server/config/healthcheck.sh diff --git a/code/config/puma.rb b/source/server/config/puma.rb similarity index 100% rename from code/config/puma.rb rename to source/server/config/puma.rb diff --git a/code/config/up.sh b/source/server/config/up.sh similarity index 100% rename from code/config/up.sh rename to source/server/config/up.sh diff --git a/code/context.rb b/source/server/context.rb similarity index 100% rename from code/context.rb rename to source/server/context.rb diff --git a/code/dispatcher.rb b/source/server/dispatcher.rb similarity index 100% rename from code/dispatcher.rb rename to source/server/dispatcher.rb diff --git a/code/empty_binding.rb b/source/server/empty_binding.rb similarity index 100% rename from code/empty_binding.rb rename to source/server/empty_binding.rb diff --git a/code/externals/asynchronous_threader.rb b/source/server/externals/asynchronous_threader.rb similarity index 100% rename from code/externals/asynchronous_threader.rb rename to source/server/externals/asynchronous_threader.rb diff --git a/code/externals/bash_sheller.rb b/source/server/externals/bash_sheller.rb similarity index 100% rename from code/externals/bash_sheller.rb rename to source/server/externals/bash_sheller.rb diff --git a/code/externals/pipe_maker.rb b/source/server/externals/pipe_maker.rb similarity index 100% rename from code/externals/pipe_maker.rb rename to source/server/externals/pipe_maker.rb diff --git a/code/externals/process_spawner.rb b/source/server/externals/process_spawner.rb similarity index 100% rename from code/externals/process_spawner.rb rename to source/server/externals/process_spawner.rb diff --git a/code/externals/random.rb b/source/server/externals/random.rb similarity index 100% rename from code/externals/random.rb rename to source/server/externals/random.rb diff --git a/code/externals/stdout_logger.rb b/source/server/externals/stdout_logger.rb similarity index 100% rename from code/externals/stdout_logger.rb rename to source/server/externals/stdout_logger.rb diff --git a/code/files_delta.rb b/source/server/files_delta.rb similarity index 100% rename from code/files_delta.rb rename to source/server/files_delta.rb diff --git a/code/gnu_unzip.rb b/source/server/gnu_unzip.rb similarity index 100% rename from code/gnu_unzip.rb rename to source/server/gnu_unzip.rb diff --git a/code/gnu_zip.rb b/source/server/gnu_zip.rb similarity index 100% rename from code/gnu_zip.rb rename to source/server/gnu_zip.rb diff --git a/code/home_files.rb b/source/server/home_files.rb similarity index 100% rename from code/home_files.rb rename to source/server/home_files.rb diff --git a/code/node.rb b/source/server/node.rb similarity index 100% rename from code/node.rb rename to source/server/node.rb diff --git a/code/prober.rb b/source/server/prober.rb similarity index 100% rename from code/prober.rb rename to source/server/prober.rb diff --git a/code/puller.rb b/source/server/puller.rb similarity index 100% rename from code/puller.rb rename to source/server/puller.rb diff --git a/code/rack_dispatcher.rb b/source/server/rack_dispatcher.rb similarity index 100% rename from code/rack_dispatcher.rb rename to source/server/rack_dispatcher.rb diff --git a/code/rag_lambdas.rb b/source/server/rag_lambdas.rb similarity index 100% rename from code/rag_lambdas.rb rename to source/server/rag_lambdas.rb diff --git a/code/runner.rb b/source/server/runner.rb similarity index 100% rename from code/runner.rb rename to source/server/runner.rb diff --git a/code/sandbox.rb b/source/server/sandbox.rb similarity index 100% rename from code/sandbox.rb rename to source/server/sandbox.rb diff --git a/code/synchronized_set.rb b/source/server/synchronized_set.rb similarity index 100% rename from code/synchronized_set.rb rename to source/server/synchronized_set.rb diff --git a/code/tagged_image_name.rb b/source/server/tagged_image_name.rb similarity index 100% rename from code/tagged_image_name.rb rename to source/server/tagged_image_name.rb diff --git a/code/tarfile_reader.rb b/source/server/tarfile_reader.rb similarity index 100% rename from code/tarfile_reader.rb rename to source/server/tarfile_reader.rb diff --git a/code/tarfile_writer.rb b/source/server/tarfile_writer.rb similarity index 100% rename from code/tarfile_writer.rb rename to source/server/tarfile_writer.rb diff --git a/code/tgz.rb b/source/server/tgz.rb similarity index 100% rename from code/tgz.rb rename to source/server/tgz.rb diff --git a/code/traffic_light.rb b/source/server/traffic_light.rb similarity index 100% rename from code/traffic_light.rb rename to source/server/traffic_light.rb diff --git a/code/utf8_clean.rb b/source/server/utf8_clean.rb similarity index 100% rename from code/utf8_clean.rb rename to source/server/utf8_clean.rb diff --git a/test/data/languages_start_points.manifests.json b/test/data/languages_start_points.manifests.json index 43b65f3f..4ee635e9 100644 --- a/test/data/languages_start_points.manifests.json +++ b/test/data/languages_start_points.manifests.json @@ -1596,12 +1596,12 @@ } } }, - "Kotlin, Kotlintest": { - "display_name": "Kotlin, Kotlintest", + "Kotlin 2.0.21, Kotlintest 5.9.1": { + "display_name": "Kotlin 2.0.21, Kotlintest 5.9.1", "filename_extension": [ ".kt" ], - "image_name": "cyberdojofoundation/kotlin_test:857e4fa", + "image_name": "ghcr.io/cyber-dojo-languages/kotlin_kotest:53adb24", "max_seconds": 20, "tab_size": 4, "visible_files": { @@ -1609,10 +1609,10 @@ "content": "package hiker\n\nfun answer():Int {\n return 6 * 9\n}\n" }, "HikerTest.kt": { - "content": "// [X] See please-help.txt \n\npackage hiker /*[X]*/\n\nimport io.kotlintest.specs.StringSpec\nimport io.kotlintest.shouldBe\nimport io.kotlintest.shouldNotBe\n\nclass HikerTest /*[X]*/ : StringSpec() {\n\n init {\n \"Example Test\" {\n hiker.answer() shouldBe 42\n }\n\n \"Other example test\" {\n \"a\" shouldNotBe \"b\"\n }\n }\n}\n" + "content": "// [X] See please-help.txt \n\npackage hiker /*[X]*/\n\nimport io.kotest.core.spec.style.StringSpec\nimport io.kotest.matchers.shouldBe\nimport io.kotest.matchers.shouldNotBe\n\n\nclass HikerTest : StringSpec() { /*[X]*/\n\n init {\n \"Example Test\" {\n hiker.answer() shouldBe 42\n }\n\n \"Other example test\" {\n \"a\" shouldNotBe \"b\"\n }\n }\n}\n" }, "cyber-dojo.sh": { - "content": "# [X] See hard-wired-test-name.txt\n\nCLASSES=.:`ls /usr/share/kotlin/kotlinc/lib/*.jar | tr '\\n' ':'`\nCLASSES=`ls /kotlin/*.jar | tr '\\n' ':'`${CLASSES}\nkotlinc *.kt -include-runtime -cp $CLASSES\nif [ $? -eq 0 ]; then\n java -cp $CLASSES \\\n io.kotlintest.runner.console.LauncherKt \\\n --writer basic \\\n --spec hiker.HikerTest # [X]\nfi\n" + "content": "# [X] See hard-wired-test-name.txt\n\nCLASSES=.:`ls /usr/share/kotlin/kotlinc/lib/*.jar | tr '\\n' ':'`\nCLASSES=`ls /kotlin/*.jar | tr '\\n' ':'`${CLASSES}\nkotlinc *.kt -include-runtime -cp $CLASSES\nif [ $? -eq 0 ]; then\n java -cp $CLASSES \\\n io.kotest.engine.launcher.MainKt \\\n --spec hiker.HikerTest \\\n --termcolor true\n # [X]\nfi\n" }, "please-help.txt": { "content": "\nA KotlinTest project usually executes with Gradle or Maven,\nand these tools know how to find all the test classes and\nexecute them one by one.\n\ncyber-dojo uses the command-line only, so we don't have that\nkind of intelligence out-of-the-box. Maybe you can help?\nIf so please email feedback@cyber-dojo.org\n\nTo get something working the test package and test class name\nis hard-wired in the cyber-dojo.sh file. If you change the\ntest package name and/or the test class name you must update\ncyber-dojo.sh appropriately.\n\nNote that cyber-dojo.sh uses the option [--writer basic]\nwhich writes red/green terminal colour codes to the output.\nThese don't render properly in a plain textarea and there appears\nto be no way to turn it off. Maybe you can help?\nIf so please email feedback@cyber-dojo.org\n\nIf you write more than one test with the same name kotlin-test\nappears to run no tests at all! Maybe you can help?\nIf so please email feedback@cyber-dojo.org\n" @@ -1701,12 +1701,12 @@ } } }, - "Python 3.12, Pytest 7.4": { - "display_name": "Python 3.12, Pytest 7.4", + "Python 3.13, Pytest 8.33": { + "display_name": "Python 3.13, Pytest 8.33", "filename_extension": [ ".py" ], - "image_name": "cyberdojofoundation/python_pytest:2b04bec", + "image_name": "ghcr.io/cyber-dojo-languages/python_pytest:3b1d90e", "max_seconds": 10, "tab_size": 4, "visible_files": { @@ -1721,14 +1721,14 @@ } } }, - "Python 3.12, approval-unittest 10.3": { - "display_name": "Python 3.12, approval-unittest 10.3", + "Python 3.13, approval-unittest 14.0": { + "display_name": "Python 3.13, approval-unittest 14.0", "filename_extension": [ ".py", ".approved.txt", ".received.txt" ], - "image_name": "cyberdojofoundation/python_approval_unittest:080dff5", + "image_name": "ghcr.io/cyber-dojo-languages/python_approval_unittest:173d501", "max_seconds": 10, "tab_size": 4, "visible_files": { @@ -1749,78 +1749,78 @@ } } }, - "Python 3.12, approvaltests-12.0.0": { - "display_name": "Python 3.12, approvaltests-12.0.0", + "Python 3.13, assert": { + "display_name": "Python 3.13, assert", "filename_extension": [ - ".py", - ".approved.txt", - ".received.txt" + ".py" ], - "image_name": "cyberdojofoundation/python_approval_pytest:0db3eb4", + "image_name": "ghcr.io/cyber-dojo-languages/python_assert:5cccb06", "max_seconds": 10, "tab_size": 4, "visible_files": { "cyber-dojo.sh": { - "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs .pytest_cache # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\n# https://github.com/approvals/ApprovalTests.Python\n# https://approvaltests.com/\n\ncoverage3 run \\\n --source=${CYBER_DOJO_SANDBOX} \\\n --module pytest \\\n --random-order-bucket=global \\\n --approvaltests-use-reporter='PythonNative'\n\n# https://coverage.readthedocs.io/en/v4.5.x/index.html\n\ncoverage3 report \\\n --show-missing \\\n > ${REPORT_DIR}/coverage.txt\n\n# http://pycodestyle.pycqa.org/en/latest/intro.html#configuration\n\npycodestyle \\\n ${CYBER_DOJO_SANDBOX} \\\n --show-source `# show source code for each error` \\\n --show-pep8 `# show relevent text from pep8` \\\n --ignore E302,E305,W293 \\\n --max-line-length=80 \\\n > ${REPORT_DIR}/style.txt\n\n# E302 expected 2 blank lines, found 0\n# E305 expected 2 blank lines after end of function or class\n# W293 blank line contains whitespace\n" + "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs .pytest_cache # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\ncoverage3 run \\\n --source=${CYBER_DOJO_SANDBOX} \\\n *test*.py\n\n# https://coverage.readthedocs.io/en/v4.5.x/index.html\n\ncoverage3 report \\\n --show-missing \\\n > ${REPORT_DIR}/coverage.txt\n\n# http://pycodestyle.pycqa.org/en/latest/intro.html#configuration\n\npycodestyle \\\n ${CYBER_DOJO_SANDBOX} \\\n --show-source `# show source code for each error` \\\n --show-pep8 `# show relevent text from pep8` \\\n --ignore E302,E305,W293 \\\n --max-line-length=80 \\\n > ${REPORT_DIR}/style.txt\n\n# E302 expected 2 blank lines, found 0\n# E305 expected 2 blank lines after end of function or class\n# W293 blank line contains whitespace\n" }, "hiker.py": { "content": "'''The starting files are unrelated to the exercise.\n\nThey simply show syntax for writing and testing\n o) a global function\n o) an instance method\nPick the style that best fits the exercise.\nThen delete the other one, along with this comment!\n'''\n\ndef global_answer():\n return 6 * 9\n\nclass Hiker:\n\n def instance_answer(self):\n return global_answer()\n" }, "test_hiker.py": { - "content": "from hiker import global_answer, Hiker\n\nfrom approvaltests import verify, Options\nfrom approvaltests.inline.inline_options import InlineOptions\n\noptions = Options().inline(InlineOptions.semi_automatic())\n\n\ndef test_global():\n \"\"\"\n 42\n \"\"\"\n result = str(global_answer())\n verify(result, options=options)\n\n\ndef test_instance():\n \"\"\"\n 42\n \"\"\"\n result = str(Hiker().instance_answer())\n verify(result, options=options)\n" + "content": "from hiker import global_answer, Hiker\n\ndef test_global_function():\n assert global_answer() == 42\n\ndef test_instance_method():\n assert Hiker().instance_answer() == 42\n\ndef green_traffic_light_pattern():\n return 'All tests passed'\n\n\nif __name__ == '__main__':\n test_global_function()\n test_instance_method()\n print(green_traffic_light_pattern())\n" } } }, - "Python 3.12, assert": { - "display_name": "Python 3.12, assert", + "Python 3.13, behave 1.2.6": { + "display_name": "Python 3.13, behave 1.2.6", "filename_extension": [ - ".py" + ".py", + ".feature" ], - "image_name": "cyberdojofoundation/python_assert:ed44c2d", + "image_name": "ghcr.io/cyber-dojo-languages/python_behave:c771064", "max_seconds": 10, "tab_size": 4, "visible_files": { "cyber-dojo.sh": { - "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs .pytest_cache # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\ncoverage3 run \\\n --source=${CYBER_DOJO_SANDBOX} \\\n *test*.py\n\n# https://coverage.readthedocs.io/en/v4.5.x/index.html\n\ncoverage3 report \\\n --show-missing \\\n > ${REPORT_DIR}/coverage.txt\n\n# http://pycodestyle.pycqa.org/en/latest/intro.html#configuration\n\npycodestyle \\\n ${CYBER_DOJO_SANDBOX} \\\n --show-source `# show source code for each error` \\\n --show-pep8 `# show relevent text from pep8` \\\n --ignore E302,E305,W293 \\\n --max-line-length=80 \\\n > ${REPORT_DIR}/style.txt\n\n# E302 expected 2 blank lines, found 0\n# E305 expected 2 blank lines after end of function or class\n# W293 blank line contains whitespace\n" + "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs .pytest_cache # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\ncoverage3 run \\\n --source=${CYBER_DOJO_SANDBOX} \\\n --module behave --no-color\n\n# https://coverage.readthedocs.io/en/v4.5.x/index.html\n\ncoverage3 report \\\n --show-missing \\\n > ${REPORT_DIR}/coverage.txt\n\n# http://pycodestyle.pycqa.org/en/latest/intro.html#configuration\n\npycodestyle \\\n ${CYBER_DOJO_SANDBOX} \\\n --show-source `# show source code for each error` \\\n --show-pep8 `# show relevent text from pep8` \\\n --ignore E302,E305,W293 \\\n --max-line-length=80 \\\n > ${REPORT_DIR}/style.txt\n\n# E302 expected 2 blank lines, found 0\n# E305 expected 2 blank lines after end of function or class\n# W293 blank line contains whitespace\n" + }, + "hiker.feature": { + "content": "\nFeature: hitch-hiker playing scrabble\n\nScenario: earthling playing scrabble in the past\nGiven the hitch-hiker selects some tiles\nWhen they spell 6 times 9\nThen the score is 42\n" }, "hiker.py": { - "content": "'''The starting files are unrelated to the exercise.\n\nThey simply show syntax for writing and testing\n o) a global function\n o) an instance method\nPick the style that best fits the exercise.\nThen delete the other one, along with this comment!\n'''\n\ndef global_answer():\n return 6 * 9\n\nclass Hiker:\n\n def instance_answer(self):\n return global_answer()\n" + "content": "class Hiker:\n\n def answer(self, first, second):\n return first * second\n" }, - "test_hiker.py": { - "content": "from hiker import global_answer, Hiker\n\ndef test_global_function():\n assert global_answer() == 42\n\ndef test_instance_method():\n assert Hiker().instance_answer() == 42\n\ndef green_traffic_light_pattern():\n return 'All tests passed'\n\n\nif __name__ == '__main__':\n test_global_function()\n test_instance_method()\n print(green_traffic_light_pattern())\n" + "steps/hiker_steps.py": { + "content": "from behave import *\nfrom hiker import Hiker\n\n\n@given(u'the hitch-hiker selects some tiles')\ndef step_impl(context):\n pass\n\n\n@when(u'they spell {tile1:d} times {tile2:d}')\ndef step_impl(context, tile1, tile2):\n douglas = Hiker()\n context.tileproduct = douglas.answer(tile1, tile2)\n\n\n@then(u'the score is {answer:d}')\ndef step_impl(context, answer):\n assert context.tileproduct is answer\n" } } }, - "Python 3.12, behave 1.2.6": { - "display_name": "Python 3.12, behave 1.2.6", + "Python 3.13, pytest-approvaltests 0.2.4-14.0": { + "display_name": "Python 3.13, pytest-approvaltests 0.2.4-14.0", "filename_extension": [ ".py", - ".feature" + ".approved.txt", + ".received.txt" ], - "image_name": "cyberdojofoundation/python_behave:aec3ec7", + "image_name": "ghcr.io/cyber-dojo-languages/python_approval_pytest:2411e61", "max_seconds": 10, "tab_size": 4, "visible_files": { "cyber-dojo.sh": { - "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs .pytest_cache # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\ncoverage3 run \\\n --source=${CYBER_DOJO_SANDBOX} \\\n --module behave --no-color\n\n# https://coverage.readthedocs.io/en/v4.5.x/index.html\n\ncoverage3 report \\\n --show-missing \\\n > ${REPORT_DIR}/coverage.txt\n\n# http://pycodestyle.pycqa.org/en/latest/intro.html#configuration\n\npycodestyle \\\n ${CYBER_DOJO_SANDBOX} \\\n --show-source `# show source code for each error` \\\n --show-pep8 `# show relevent text from pep8` \\\n --ignore E302,E305,W293 \\\n --max-line-length=80 \\\n > ${REPORT_DIR}/style.txt\n\n# E302 expected 2 blank lines, found 0\n# E305 expected 2 blank lines after end of function or class\n# W293 blank line contains whitespace\n" - }, - "hiker.feature": { - "content": "\nFeature: hitch-hiker playing scrabble\n\nScenario: earthling playing scrabble in the past\nGiven the hitch-hiker selects some tiles\nWhen they spell 6 times 9\nThen the score is 42\n" + "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs .pytest_cache # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\n# https://github.com/approvals/ApprovalTests.Python\n# https://approvaltests.com/\n\ncoverage3 run \\\n --source=${CYBER_DOJO_SANDBOX} \\\n --module pytest \\\n --random-order-bucket=global \\\n --approvaltests-use-reporter='PythonNative'\n\n# https://coverage.readthedocs.io/en/v4.5.x/index.html\n\ncoverage3 report \\\n --show-missing \\\n > ${REPORT_DIR}/coverage.txt\n\n# http://pycodestyle.pycqa.org/en/latest/intro.html#configuration\n\npycodestyle \\\n ${CYBER_DOJO_SANDBOX} \\\n --show-source `# show source code for each error` \\\n --show-pep8 `# show relevent text from pep8` \\\n --ignore E302,E305,W293 \\\n --max-line-length=80 \\\n > ${REPORT_DIR}/style.txt\n\n# E302 expected 2 blank lines, found 0\n# E305 expected 2 blank lines after end of function or class\n# W293 blank line contains whitespace\n" }, "hiker.py": { - "content": "class Hiker:\n\n def answer(self, first, second):\n return first * second\n" + "content": "'''The starting files are unrelated to the exercise.\n\nThey simply show syntax for writing and testing\n o) a global function\n o) an instance method\nPick the style that best fits the exercise.\nThen delete the other one, along with this comment!\n'''\n\ndef global_answer():\n return 6 * 9\n\nclass Hiker:\n\n def instance_answer(self):\n return global_answer()\n" }, - "steps/hiker_steps.py": { - "content": "from behave import *\nfrom hiker import Hiker\n\n\n@given(u'the hitch-hiker selects some tiles')\ndef step_impl(context):\n pass\n\n\n@when(u'they spell {tile1:d} times {tile2:d}')\ndef step_impl(context, tile1, tile2):\n douglas = Hiker()\n context.tileproduct = douglas.answer(tile1, tile2)\n\n\n@then(u'the score is {answer:d}')\ndef step_impl(context, answer):\n assert context.tileproduct is answer\n" + "test_hiker.py": { + "content": "from hiker import global_answer, Hiker\n\nfrom approvaltests import verify, Options\nfrom approvaltests.inline.inline_options import InlineOptions\n\noptions = Options().inline(InlineOptions.semi_automatic())\n\n\ndef test_global():\n \"\"\"\n 42\n \"\"\"\n result = str(global_answer())\n verify(result, options=options)\n\n\ndef test_instance():\n \"\"\"\n 42\n \"\"\"\n result = str(Hiker().instance_answer())\n verify(result, options=options)\n" } } }, - "Python 3.12, unittest": { - "display_name": "Python 3.12, unittest", + "Python 3.13, unittest": { + "display_name": "Python 3.13, unittest", "filename_extension": [ ".py" ], - "image_name": "cyberdojofoundation/python_unittest:0deeb77", + "image_name": "ghcr.io/cyber-dojo-languages/python_unittest:044077e", "progress_regexs": [ "FAILED \\(failures=\\d+\\)", "OK" @@ -1954,7 +1954,7 @@ "content": "require 'simplecov'\nrequire 'simplecov-console'\nrequire 'stringio'\n\n$exception_raised = false\n\nmodule SimpleCov\n module Formatter\n class FileWriter\n def format(result)\n unless amber_traffic_light?\n stdout = capture_stdout {\n SimpleCov::Formatter::Console.new.format(result)\n }\n `mkdir #{report_dir} 2> /dev/null`\n IO.write(\"#{report_dir}/coverage.txt\", stdout)\n end\n end\n def amber_traffic_light?\n $exception_raised\n end\n def report_dir\n \"#{ENV['CYBER_DOJO_SANDBOX']}/report\"\n end\n def capture_stdout\n begin\n uncaptured_stdout = $stdout\n captured_stdout = StringIO.new('', 'w')\n $stdout = captured_stdout\n yield\n $stdout.string\n ensure\n $stdout = uncaptured_stdout\n end\n end\n end\n end\nend\n\nSimpleCov.command_name(\"MiniTest\")\nSimpleCov.formatter = SimpleCov::Formatter::FileWriter\nSimpleCov.start\n\nat_exit do\n # Can't use SimpleCov.at_exit; when the call reaches\n # FileWriter.format() there is no longer an exception\n # I'd like to only write the coverage report if the\n # traffic-light is green but it seems there is no way.\n $exception_raised = true\nend\n" }, "cyber-dojo.sh": { - "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs coverage # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\n# turn off colour for new coverage report\nexport NO_COLOR=1\n\nfor test_file in *test*.rb\ndo\n ruby $test_file\ndone\n" + "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs coverage # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\n# turn off colour for new coverage report\nexport NO_COLOR=1\n\nfor test_file in *test*.rb\ndo\n ruby $test_file || true\ndone\n" }, "hiker.rb": { "content": "# The starting files are unrelated to the exercise.\n#\n# They simply show syntax for writing and testing\n# o) a global function\n# o) an instance method\n# Pick the style that best fits the exercise.\n# Then delete the other one, along with this comment!\n\ndef global_answer\n 6 * 9\nend\n\nclass Hiker\n\n def instance_answer\n global_answer\n end\n\nend\n" @@ -2000,7 +2000,7 @@ "content": "require 'simplecov'\nrequire 'simplecov-console'\nrequire 'stringio'\n\nmodule SimpleCov\n module Formatter\n class FileWriter\n def format(result)\n stdout = capture_stdout {\n SimpleCov::Formatter::Console.new.format(result)\n }\n `mkdir #{report_dir} 2> /dev/null`\n IO.write(\"#{report_dir}/coverage.txt\", stdout)\n end\n def report_dir\n \"#{ENV['CYBER_DOJO_SANDBOX']}/report\"\n end\n def capture_stdout\n begin\n uncaptured_stdout = $stdout\n captured_stdout = StringIO.new('', 'w')\n $stdout = captured_stdout\n yield\n $stdout.string\n ensure\n $stdout = uncaptured_stdout\n end\n end\n end\n end\nend\n\nSimpleCov.command_name \"Test::Unit\"\nSimpleCov.at_exit do\n # I'd like to only write the coverage report if the\n # traffic-light is green but it seems there is no way.\n if $!.is_a?(SystemExit) # !amber-traffic-light\n SimpleCov::Formatter::FileWriter.new.format(SimpleCov.result)\n end\nend\nSimpleCov.start\n" }, "cyber-dojo.sh": { - "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs coverage # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\n# turn off colour for new coverage report\nexport NO_COLOR=1\n\nfor test_file in *test*.rb\ndo\n ruby $test_file\ndone\n" + "content": "set -e\n\n# --------------------------------------------------------------\n# Text files under /sandbox are automatically returned...\nsource ~/cyber_dojo_fs_cleaners.sh\nexport REPORT_DIR=${CYBER_DOJO_SANDBOX}/report\nfunction cyber_dojo_enter()\n{\n # 1. Only return _newly_ generated reports.\n cyber_dojo_reset_dirs ${REPORT_DIR}\n}\nfunction cyber_dojo_exit()\n{\n # 2. Remove text files we don't want returned.\n cyber_dojo_delete_dirs coverage # ...\n #cyber_dojo_delete_files ...\n}\ncyber_dojo_enter\ntrap cyber_dojo_exit EXIT SIGTERM\n# --------------------------------------------------------------\n\n# turn off colour for new coverage report\nexport NO_COLOR=1\n\nfor test_file in *test*.rb\ndo\n ruby $test_file || true\ndone\n" }, "hiker.rb": { "content": "# The starting files are unrelated to the exercise.\n#\n# They simply show syntax for writing and testing\n# o) a global function\n# o) an instance method\n# Pick the style that best fits the exercise.\n# Then delete the other one, along with this comment!\n\ndef global_answer\n 6 * 9\nend\n\nclass Hiker\n\n def instance_answer\n global_answer\n end\n\nend\n" @@ -2010,12 +2010,12 @@ } } }, - "Rust, test": { - "display_name": "Rust, test", + "Rust 1.81, test": { + "display_name": "Rust 1.81, test", "filename_extension": [ ".rs" ], - "image_name": "cyberdojofoundation/rust_test:1e0565d", + "image_name": "ghcr.io/cyber-dojo-languages/rust_test:67ed02f", "max_seconds": 10, "tab_size": 4, "visible_files": { diff --git a/test/lib/coverage.rb b/test/lib/coverage.rb index f78f7e71..90451701 100644 --- a/test/lib/coverage.rb +++ b/test/lib/coverage.rb @@ -14,11 +14,12 @@ def runner_nocov_token # add_group('debug') { |src| puts src.filename; false } code_dir = ENV.fetch('CODE_DIR', nil) test_dir = ENV.fetch('TEST_DIR', nil) - add_group(code_dir) { |src| src.filename =~ %r{^/runner/#{code_dir}/} } add_group(test_dir) { |src| src.filename =~ %r{^/runner/#{test_dir}/.*_test\.rb$} } + add_group(code_dir) { |src| src.filename !~ %r{^/runner/#{test_dir}}} end -SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([ - SimpleCov::Formatter::HTMLFormatter, - SimpleCov::Formatter::JSONFormatter - ]) +formatters = [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::JSONFormatter +] +SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(formatters) diff --git a/test/require_code.rb b/test/require_code.rb index e532bc59..30800d74 100644 --- a/test/require_code.rb +++ b/test/require_code.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true def require_code(required) - require_relative "../code/#{required}" + require_relative "../#{required}" end def require_server_code(required) diff --git a/test/server/traffic_light_test.rb b/test/server/traffic_light_test.rb index b1f12b47..56131eee 100644 --- a/test/server/traffic_light_test.rb +++ b/test/server/traffic_light_test.rb @@ -138,7 +138,7 @@ def id58_setup "exception when eval'ing lambda source", lambda_source, 'SyntaxError', - ["(eval at /runner/code/traffic_light.rb:86):1: syntax error, unexpected '-'", + ["(eval at /runner/traffic_light.rb:86):1: syntax error, unexpected '-'", 'not-a-lambda', ' ^', ''].join("\n") From 832a7916083a81fd5a97ca87e532cfaacc8549f2 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sun, 27 Oct 2024 08:43:15 +0000 Subject: [PATCH 2/8] Update dependent_display_names --- sh/setup_dependent_images.sh | 16 ++++++++++++++++ test/dependent_display_names.rb | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/sh/setup_dependent_images.sh b/sh/setup_dependent_images.sh index ac68bb01..12d6cd0d 100755 --- a/sh/setup_dependent_images.sh +++ b/sh/setup_dependent_images.sh @@ -41,6 +41,22 @@ pull_dependent_images() | while read display_name do local image_name=$(echo "${JSON_DATA}" | jq --raw-output ".[\"${display_name}\"].image_name") + if [ "${image_name}" == "null" ]; then + echo "ERROR: ${display_name}" + echo "Has no entry in test/dependent_display_names.rb" + echo "This is probably because of a language and/or unit-test framework upgrade." + echo "Possible updated display_names are:" + local -r lang=$(echo "${display_name}" | awk '{print $1;}') + local -r all_names=$(echo "${JSON_DATA}" | jq 'keys') + echo "${all_names}" | while read name + do + if [[ "${name:1}" =~ ^${lang} ]]; then + echo "${name}" + fi + done + exit 42 + fi + echo "image_name=:${image_name}:" if ! echo "${IMAGE_NAMES}" | grep "${image_name}" ; then docker pull "${image_name}" fi diff --git a/test/dependent_display_names.rb b/test/dependent_display_names.rb index 6bdcbf2a..d3624cf8 100644 --- a/test/dependent_display_names.rb +++ b/test/dependent_display_names.rb @@ -7,7 +7,7 @@ def run DisplayNames::ALPINE, DisplayNames::DEBIAN, DisplayNames::UBUNTU, - 'Python 3.12, Pytest 7.4', # Used in traffic-light tests + 'Python 3.13, Pytest 8.33', # Used in traffic-light tests # Client-side tests 'VisualBasic, NUnit' ].each do |display_name| From 1a90201a75a6f5c88bd1ae0a8236a938be95f3f0 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sun, 27 Oct 2024 10:59:18 +0000 Subject: [PATCH 3/8] Tidy bash script --- sh/setup_dependent_images.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/sh/setup_dependent_images.sh b/sh/setup_dependent_images.sh index 12d6cd0d..1cb99828 100755 --- a/sh/setup_dependent_images.sh +++ b/sh/setup_dependent_images.sh @@ -3,7 +3,6 @@ set -Eeu repo_root() { git rev-parse --show-toplevel; } -# - - - - - - - - - - - - - - - - - - - - - - - - setup_dependent_images() { if [ "${1:-}" != server ]; then @@ -12,7 +11,6 @@ setup_dependent_images() remove_pulled_image } -# - - - - - - - - - - - - - - - - - - - - - - - - pull_dependent_images() { echo @@ -63,7 +61,6 @@ pull_dependent_images() done } -# - - - - - - - - - - - - - - - - - - - - - - - - remove_pulled_image() { echo From 675c421d1ff6628afb0e787936f53b75afa441c5 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sun, 27 Oct 2024 11:09:29 +0000 Subject: [PATCH 4/8] Remove debug echo --- sh/setup_dependent_images.sh | 1 - {client => source/client}/.dockerignore | 0 {client => source/client}/Dockerfile | 0 {client/code => source/client}/config/config.ru | 0 {client/code => source/client}/config/healthcheck.sh | 0 {client/code => source/client}/config/puma.rb | 0 {client/code => source/client}/config/up.sh | 0 {client/code => source/client}/context.rb | 0 {client/code => source/client}/demo.rb | 0 {client/code => source/client}/dispatcher.rb | 0 {client/code => source/client}/http_proxy/json_requester.rb | 0 {client/code => source/client}/http_proxy/json_responder.rb | 0 .../code => source/client}/http_proxy/languages_start_points.rb | 0 {client/code => source/client}/http_proxy/net_http_adapter.rb | 0 {client/code => source/client}/http_proxy/runner.rb | 0 {client/code => source/client}/prober.rb | 0 {client/code => source/client}/rack_dispatcher.rb | 0 17 files changed, 1 deletion(-) rename {client => source/client}/.dockerignore (100%) rename {client => source/client}/Dockerfile (100%) rename {client/code => source/client}/config/config.ru (100%) rename {client/code => source/client}/config/healthcheck.sh (100%) rename {client/code => source/client}/config/puma.rb (100%) rename {client/code => source/client}/config/up.sh (100%) rename {client/code => source/client}/context.rb (100%) rename {client/code => source/client}/demo.rb (100%) rename {client/code => source/client}/dispatcher.rb (100%) rename {client/code => source/client}/http_proxy/json_requester.rb (100%) rename {client/code => source/client}/http_proxy/json_responder.rb (100%) rename {client/code => source/client}/http_proxy/languages_start_points.rb (100%) rename {client/code => source/client}/http_proxy/net_http_adapter.rb (100%) rename {client/code => source/client}/http_proxy/runner.rb (100%) rename {client/code => source/client}/prober.rb (100%) rename {client/code => source/client}/rack_dispatcher.rb (100%) diff --git a/sh/setup_dependent_images.sh b/sh/setup_dependent_images.sh index 1cb99828..16be1cd6 100755 --- a/sh/setup_dependent_images.sh +++ b/sh/setup_dependent_images.sh @@ -54,7 +54,6 @@ pull_dependent_images() done exit 42 fi - echo "image_name=:${image_name}:" if ! echo "${IMAGE_NAMES}" | grep "${image_name}" ; then docker pull "${image_name}" fi diff --git a/client/.dockerignore b/source/client/.dockerignore similarity index 100% rename from client/.dockerignore rename to source/client/.dockerignore diff --git a/client/Dockerfile b/source/client/Dockerfile similarity index 100% rename from client/Dockerfile rename to source/client/Dockerfile diff --git a/client/code/config/config.ru b/source/client/config/config.ru similarity index 100% rename from client/code/config/config.ru rename to source/client/config/config.ru diff --git a/client/code/config/healthcheck.sh b/source/client/config/healthcheck.sh similarity index 100% rename from client/code/config/healthcheck.sh rename to source/client/config/healthcheck.sh diff --git a/client/code/config/puma.rb b/source/client/config/puma.rb similarity index 100% rename from client/code/config/puma.rb rename to source/client/config/puma.rb diff --git a/client/code/config/up.sh b/source/client/config/up.sh similarity index 100% rename from client/code/config/up.sh rename to source/client/config/up.sh diff --git a/client/code/context.rb b/source/client/context.rb similarity index 100% rename from client/code/context.rb rename to source/client/context.rb diff --git a/client/code/demo.rb b/source/client/demo.rb similarity index 100% rename from client/code/demo.rb rename to source/client/demo.rb diff --git a/client/code/dispatcher.rb b/source/client/dispatcher.rb similarity index 100% rename from client/code/dispatcher.rb rename to source/client/dispatcher.rb diff --git a/client/code/http_proxy/json_requester.rb b/source/client/http_proxy/json_requester.rb similarity index 100% rename from client/code/http_proxy/json_requester.rb rename to source/client/http_proxy/json_requester.rb diff --git a/client/code/http_proxy/json_responder.rb b/source/client/http_proxy/json_responder.rb similarity index 100% rename from client/code/http_proxy/json_responder.rb rename to source/client/http_proxy/json_responder.rb diff --git a/client/code/http_proxy/languages_start_points.rb b/source/client/http_proxy/languages_start_points.rb similarity index 100% rename from client/code/http_proxy/languages_start_points.rb rename to source/client/http_proxy/languages_start_points.rb diff --git a/client/code/http_proxy/net_http_adapter.rb b/source/client/http_proxy/net_http_adapter.rb similarity index 100% rename from client/code/http_proxy/net_http_adapter.rb rename to source/client/http_proxy/net_http_adapter.rb diff --git a/client/code/http_proxy/runner.rb b/source/client/http_proxy/runner.rb similarity index 100% rename from client/code/http_proxy/runner.rb rename to source/client/http_proxy/runner.rb diff --git a/client/code/prober.rb b/source/client/prober.rb similarity index 100% rename from client/code/prober.rb rename to source/client/prober.rb diff --git a/client/code/rack_dispatcher.rb b/source/client/rack_dispatcher.rb similarity index 100% rename from client/code/rack_dispatcher.rb rename to source/client/rack_dispatcher.rb From 69fbf017a1b4606cb33d0c85290aa9090a72875f Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sun, 27 Oct 2024 11:09:48 +0000 Subject: [PATCH 5/8] Move client code into source/client/ dir --- docker-compose.yml | 2 +- source/client/.dockerignore | 2 -- source/client/Dockerfile | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1caa4990..4621f910 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: client: build: - context: client + context: source/client args: [ COMMIT_SHA ] image: ${CYBER_DOJO_RUNNER_CLIENT_IMAGE}:${CYBER_DOJO_RUNNER_TAG} user: ${CYBER_DOJO_RUNNER_CLIENT_USER} diff --git a/source/client/.dockerignore b/source/client/.dockerignore index 33a36ea5..e69de29b 100644 --- a/source/client/.dockerignore +++ b/source/client/.dockerignore @@ -1,2 +0,0 @@ -* -!code/ diff --git a/source/client/Dockerfile b/source/client/Dockerfile index ed9088fb..ceea3e67 100644 --- a/source/client/Dockerfile +++ b/source/client/Dockerfile @@ -8,6 +8,6 @@ ARG COMMIT_SHA ENV SHA=${COMMIT_SHA} USER nobody -HEALTHCHECK --interval=1s --timeout=1s --retries=5 --start-period=5s CMD /runner/code/config/healthcheck.sh +HEALTHCHECK --interval=1s --timeout=1s --retries=5 --start-period=5s CMD /runner/config/healthcheck.sh ENTRYPOINT ["/sbin/tini", "-g", "--"] -CMD [ "/runner/code/config/up.sh" ] +CMD [ "/runner/config/up.sh" ] From 837a99c9c49532524dcbca8b2a3f0a51ba84b264 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Sun, 27 Oct 2024 11:19:39 +0000 Subject: [PATCH 6/8] Fix altered paths in rubocop config file --- .github/workflows/main.yml | 2 +- .rubocop.yml | 72 +++++++++++++++++--------------------- Makefile | 6 ++-- test/lib/coverage.rb | 2 +- 4 files changed, 38 insertions(+), 44 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5097b62a..295ce525 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,7 +91,7 @@ jobs: - name: Run Rubocop lint on source id: lint run: - make lint + make rubocop_lint - name: Setup Kosli CLI if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }} diff --git a/.rubocop.yml b/.rubocop.yml index b314a250..7c93014c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,13 +8,13 @@ Lint/EmptyBlock: Layout/EmptyLineAfterMagicComment: Exclude: - - code/**/* - - client/code/**/* + - source/server/**/* + - source/client/**/* - test/**/* Layout/LineLength: Exclude: - - client/code/demo.rb + - source/client/demo.rb - test/lib/simplecov_json.rb Lint/PercentStringArray: @@ -23,11 +23,9 @@ Lint/PercentStringArray: Lint/RescueException: Exclude: - - client/code/dispatcher.rb - - client/code/rack_dispatcher.rb - - code/dispatcher.rb - - code/rack_dispatcher.rb - - code/traffic_light.rb + - source/*/dispatcher.rb + - source/*/rack_dispatcher.rb + - source/server/traffic_light.rb Lint/ShadowingOuterLocalVariable: Exclude: @@ -36,22 +34,21 @@ Lint/ShadowingOuterLocalVariable: # I often give an inline expression a name for readability Lint/UselessAssignment: Exclude: - - code/**/* + - source/**/* - test/**/* Lint/UselessMethodDefinition: Exclude: - - code/empty_binding.rb + - source/server/empty_binding.rb Metrics/AbcSize: Exclude: - test/**/* - - code/runner.rb - - code/dispatcher.rb - - code/context.rb - - code/capture3_with_timeout.rb - - client/code/dispatcher.rb - - client/code/demo.rb + - source/server/runner.rb + - source/*/dispatcher.rb + - source/server/context.rb + - source/server/capture3_with_timeout.rb + - source/client/demo.rb Metrics/BlockLength: Exclude: @@ -60,38 +57,36 @@ Metrics/BlockLength: Metrics/ClassLength: Exclude: - test/**/* - - code/runner.rb - - client/code/demo.rb + - source/server/runner.rb + - source/client/demo.rb Metrics/CyclomaticComplexity: Exclude: - - client/code/dispatcher.rb - - code/context.rb - - code/dispatcher.rb + - source/*/dispatcher.rb + - source/server/context.rb - test/id58_test_base.rb Metrics/MethodLength: Exclude: - test/**/* - - code/traffic_light.rb - - code/tagged_image_name.rb - - code/runner.rb - - code/puller.rb - - code/files_delta.rb - - code/externals/bash_sheller.rb - - code/dispatcher.rb - - code/capture3_with_timeout.rb - - client/code/dispatcher.rb - - client/code/demo.rb - - code/home_files.rb + - source/server/traffic_light.rb + - source/server/tagged_image_name.rb + - source/server/runner.rb + - source/server/puller.rb + - source/server/files_delta.rb + - source/server/externals/bash_sheller.rb + - source/*/dispatcher.rb + - source/server/capture3_with_timeout.rb + - source/client/demo.rb + - source/server/home_files.rb Metrics/ParameterLists: Exclude: - - code/runner.rb + - source/server/runner.rb Metrics/PerceivedComplexity: Exclude: - - code/context.rb + - source/server/context.rb Naming/VariableNumber: Exclude: @@ -105,8 +100,7 @@ Style/ClassVars: Style/Documentation: Exclude: - - code/**/* - - client/code/**/* + - source/*/**/* - test/**/* Style/FormatStringToken: @@ -115,8 +109,8 @@ Style/FormatStringToken: Style/FrozenStringLiteralComment: Exclude: - - code/gnu_zip.rb - - code/tarfile_writer.rb + - source/server/gnu_zip.rb + - source/server/tarfile_writer.rb - test/test_base.rb Style/MissingRespondToMissing: @@ -125,7 +119,7 @@ Style/MissingRespondToMissing: Style/RedundantInitialize: Exclude: - - code/prober.rb + - source/server/prober.rb Style/StringConcatenation: Exclude: diff --git a/Makefile b/Makefile index 7903608a..1c0be6cf 100644 --- a/Makefile +++ b/Makefile @@ -7,9 +7,6 @@ IMAGE_NAME := cyberdojo/runner:${SHORT_SHA} image: ${PWD}/sh/build_tag.sh -lint: - ${PWD}/sh/lint.sh - unit_test: image ${PWD}/sh/test.sh server @@ -18,6 +15,9 @@ integration_test: image test: unit_test integration_test +rubocop_lint: + docker run --rm --volume "${PWD}:/app" cyberdojo/rubocop --raise-cop-error + demo: ${PWD}/sh/demo.sh diff --git a/test/lib/coverage.rb b/test/lib/coverage.rb index 90451701..26798c9b 100644 --- a/test/lib/coverage.rb +++ b/test/lib/coverage.rb @@ -15,7 +15,7 @@ def runner_nocov_token code_dir = ENV.fetch('CODE_DIR', nil) test_dir = ENV.fetch('TEST_DIR', nil) add_group(test_dir) { |src| src.filename =~ %r{^/runner/#{test_dir}/.*_test\.rb$} } - add_group(code_dir) { |src| src.filename !~ %r{^/runner/#{test_dir}}} + add_group(code_dir) { |src| src.filename !~ %r{^/runner/#{test_dir}} } end formatters = [ From aef691c2213c64cde6d17af174a99f1e95e58eb0 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Mon, 28 Oct 2024 07:55:46 +0000 Subject: [PATCH 7/8] Rename sh/ dir to bin/ --- CONTRIBUTING.md | 2 +- Makefile | 10 ++++---- bin/build_tag.sh | 13 ++++++++++ {sh => bin}/build_tagged_images.sh | 0 {sh => bin}/containers_down.sh | 0 .../containers_up_healthy_and_clean.sh | 0 .../create_test_data_manifests_file.sh | 0 {sh => bin}/demo.sh | 8 +++---- {sh => bin}/echo_versioner_env_vars.sh | 0 {sh => bin}/exit_non_zero_unless_installed.sh | 0 {sh => bin}/exit_zero_if_build_only.sh | 0 {sh => bin}/exit_zero_if_show_help.sh | 0 {sh => bin}/lint.sh | 0 {sh => bin}/remove_old_images.sh | 0 {sh => bin}/remove_zombie_containers.sh | 0 {sh => bin}/setup_dependent_images.sh | 0 bin/test.sh | 24 +++++++++++++++++++ {sh => bin}/test_in_containers.sh | 0 build_test.sh | 15 ------------ sh/build_tag.sh | 13 ---------- sh/test.sh | 24 ------------------- 21 files changed, 46 insertions(+), 63 deletions(-) create mode 100755 bin/build_tag.sh rename {sh => bin}/build_tagged_images.sh (100%) rename {sh => bin}/containers_down.sh (100%) rename {sh => bin}/containers_up_healthy_and_clean.sh (100%) rename {sh => bin}/create_test_data_manifests_file.sh (100%) rename {sh => bin}/demo.sh (70%) rename {sh => bin}/echo_versioner_env_vars.sh (100%) rename {sh => bin}/exit_non_zero_unless_installed.sh (100%) rename {sh => bin}/exit_zero_if_build_only.sh (100%) rename {sh => bin}/exit_zero_if_show_help.sh (100%) rename {sh => bin}/lint.sh (100%) rename {sh => bin}/remove_old_images.sh (100%) rename {sh => bin}/remove_zombie_containers.sh (100%) rename {sh => bin}/setup_dependent_images.sh (100%) create mode 100755 bin/test.sh rename {sh => bin}/test_in_containers.sh (100%) delete mode 100755 build_test.sh delete mode 100755 sh/build_tag.sh delete mode 100755 sh/test.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5de4368..301e083b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,5 +3,5 @@ :+1::tada: Thanks for thinking about contributing! :tada::+1: -There is a cyber-dojo [Project Board](https://github.com/orgs/cyber-dojo/projects/3/views/1) There is a central [CONTRIBUTING.md](https://github.com/cyber-dojo/cyber-dojo/blob/master/CONTRIBUTING.md) +There is a cyber-dojo [Project Board](https://github.com/orgs/cyber-dojo/projects/3/views/1) diff --git a/Makefile b/Makefile index 1c0be6cf..027b7a91 100644 --- a/Makefile +++ b/Makefile @@ -2,16 +2,14 @@ SHORT_SHA := $(shell git rev-parse HEAD | head -c7) IMAGE_NAME := cyberdojo/runner:${SHORT_SHA} -.PHONY: image lint unit_test integration_test test demo snyk-container snyk-code - image: - ${PWD}/sh/build_tag.sh + ${PWD}/bin/build_tag.sh unit_test: image - ${PWD}/sh/test.sh server + ${PWD}/bin/test.sh server integration_test: image - ${PWD}/sh/test.sh client + ${PWD}/bin/test.sh client test: unit_test integration_test @@ -19,7 +17,7 @@ rubocop_lint: docker run --rm --volume "${PWD}:/app" cyberdojo/rubocop --raise-cop-error demo: - ${PWD}/sh/demo.sh + ${PWD}/bin/demo.sh snyk-container: image snyk container test ${IMAGE_NAME} \ diff --git a/bin/build_tag.sh b/bin/build_tag.sh new file mode 100755 index 00000000..b344cde5 --- /dev/null +++ b/bin/build_tag.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -Eeu + +repo_root() { git rev-parse --show-toplevel; } +export BIN_DIR="$(repo_root)/bin" + +source "${BIN_DIR}/build_tagged_images.sh" +source "${BIN_DIR}/remove_old_images.sh" +source "${BIN_DIR}/echo_versioner_env_vars.sh" +export $(echo_versioner_env_vars) + +remove_old_images +build_tagged_images "$@" diff --git a/sh/build_tagged_images.sh b/bin/build_tagged_images.sh similarity index 100% rename from sh/build_tagged_images.sh rename to bin/build_tagged_images.sh diff --git a/sh/containers_down.sh b/bin/containers_down.sh similarity index 100% rename from sh/containers_down.sh rename to bin/containers_down.sh diff --git a/sh/containers_up_healthy_and_clean.sh b/bin/containers_up_healthy_and_clean.sh similarity index 100% rename from sh/containers_up_healthy_and_clean.sh rename to bin/containers_up_healthy_and_clean.sh diff --git a/sh/create_test_data_manifests_file.sh b/bin/create_test_data_manifests_file.sh similarity index 100% rename from sh/create_test_data_manifests_file.sh rename to bin/create_test_data_manifests_file.sh diff --git a/sh/demo.sh b/bin/demo.sh similarity index 70% rename from sh/demo.sh rename to bin/demo.sh index 162e0b2c..8fcbcd4c 100755 --- a/sh/demo.sh +++ b/bin/demo.sh @@ -2,14 +2,14 @@ set -Ee repo_root() { git rev-parse --show-toplevel; } -export SH_DIR="$(repo_root)/sh" +export BIN_DIR="$(repo_root)/bin" readonly TMP_DIR=/tmp readonly DEMO_FILENAME="${TMP_DIR}/runner_demo.html" readonly DEMO_URL="file://${DEMO_FILENAME}" -source "${SH_DIR}/build_tagged_images.sh" -source "${SH_DIR}/containers_up_healthy_and_clean.sh" -source "${SH_DIR}/echo_versioner_env_vars.sh" +source "${BIN_DIR}/build_tagged_images.sh" +source "${BIN_DIR}/containers_up_healthy_and_clean.sh" +source "${BIN_DIR}/echo_versioner_env_vars.sh" export $(echo_versioner_env_vars) run_demo() { docker exec -it test_runner_client ruby /runner/code/demo.rb > "${DEMO_FILENAME}"; } diff --git a/sh/echo_versioner_env_vars.sh b/bin/echo_versioner_env_vars.sh similarity index 100% rename from sh/echo_versioner_env_vars.sh rename to bin/echo_versioner_env_vars.sh diff --git a/sh/exit_non_zero_unless_installed.sh b/bin/exit_non_zero_unless_installed.sh similarity index 100% rename from sh/exit_non_zero_unless_installed.sh rename to bin/exit_non_zero_unless_installed.sh diff --git a/sh/exit_zero_if_build_only.sh b/bin/exit_zero_if_build_only.sh similarity index 100% rename from sh/exit_zero_if_build_only.sh rename to bin/exit_zero_if_build_only.sh diff --git a/sh/exit_zero_if_show_help.sh b/bin/exit_zero_if_show_help.sh similarity index 100% rename from sh/exit_zero_if_show_help.sh rename to bin/exit_zero_if_show_help.sh diff --git a/sh/lint.sh b/bin/lint.sh similarity index 100% rename from sh/lint.sh rename to bin/lint.sh diff --git a/sh/remove_old_images.sh b/bin/remove_old_images.sh similarity index 100% rename from sh/remove_old_images.sh rename to bin/remove_old_images.sh diff --git a/sh/remove_zombie_containers.sh b/bin/remove_zombie_containers.sh similarity index 100% rename from sh/remove_zombie_containers.sh rename to bin/remove_zombie_containers.sh diff --git a/sh/setup_dependent_images.sh b/bin/setup_dependent_images.sh similarity index 100% rename from sh/setup_dependent_images.sh rename to bin/setup_dependent_images.sh diff --git a/bin/test.sh b/bin/test.sh new file mode 100755 index 00000000..b216e28c --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -Eeu + +repo_root() { git rev-parse --show-toplevel; } +export BIN_DIR="$(repo_root)/bin" + +source "${BIN_DIR}/containers_down.sh" +source "${BIN_DIR}/containers_up_healthy_and_clean.sh" +source "${BIN_DIR}/create_test_data_manifests_file.sh" +source "${BIN_DIR}/remove_zombie_containers.sh" +source "${BIN_DIR}/setup_dependent_images.sh" +source "${BIN_DIR}/test_in_containers.sh" + +source "${BIN_DIR}/echo_versioner_env_vars.sh" +export $(echo_versioner_env_vars) + +remove_zombie_containers +containers_down +setup_dependent_images "$@" +create_test_data_manifests_file +server_up_healthy_and_clean +client_up_healthy_and_clean "$@" +test_in_containers "$@" +containers_down diff --git a/sh/test_in_containers.sh b/bin/test_in_containers.sh similarity index 100% rename from sh/test_in_containers.sh rename to bin/test_in_containers.sh diff --git a/build_test.sh b/build_test.sh deleted file mode 100755 index 0fec3ad2..00000000 --- a/build_test.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -Eeu - -repo_root() { git rev-parse --show-toplevel; } -export SH_DIR="$(repo_root)/sh" -source "${SH_DIR}/exit_non_zero_unless_installed.sh" -source "${SH_DIR}/exit_zero_if_build_only.sh" -source "${SH_DIR}/exit_zero_if_show_help.sh" - -exit_zero_if_show_help "$@" -exit_non_zero_unless_installed docker jq - -"${SH_DIR}/build_tag.sh" "$@" -exit_zero_if_build_only "$@" -"${SH_DIR}/test.sh" "$@" diff --git a/sh/build_tag.sh b/sh/build_tag.sh deleted file mode 100755 index 3feb847d..00000000 --- a/sh/build_tag.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -set -Eeu - -repo_root() { git rev-parse --show-toplevel; } -export SH_DIR="$(repo_root)/sh" - -source "${SH_DIR}/build_tagged_images.sh" -source "${SH_DIR}/remove_old_images.sh" -source "${SH_DIR}/echo_versioner_env_vars.sh" -export $(echo_versioner_env_vars) - -remove_old_images -build_tagged_images "$@" diff --git a/sh/test.sh b/sh/test.sh deleted file mode 100755 index 2eef9a38..00000000 --- a/sh/test.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -set -Eeu - -repo_root() { git rev-parse --show-toplevel; } -export SH_DIR="$(repo_root)/sh" - -source "${SH_DIR}/containers_down.sh" -source "${SH_DIR}/containers_up_healthy_and_clean.sh" -source "${SH_DIR}/create_test_data_manifests_file.sh" -source "${SH_DIR}/remove_zombie_containers.sh" -source "${SH_DIR}/setup_dependent_images.sh" -source "${SH_DIR}/test_in_containers.sh" - -source "${SH_DIR}/echo_versioner_env_vars.sh" -export $(echo_versioner_env_vars) - -remove_zombie_containers -containers_down -setup_dependent_images "$@" -create_test_data_manifests_file -server_up_healthy_and_clean -client_up_healthy_and_clean "$@" -test_in_containers "$@" -containers_down From e9d27a2e19395cf4e88214cd309bfc67cc74c102 Mon Sep 17 00:00:00 2001 From: JonJagger Date: Mon, 28 Oct 2024 08:05:15 +0000 Subject: [PATCH 8/8] Dockerfile: update base image to move past new snyk vulnerability --- Dockerfile | 2 +- source/client/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0e6e9f3a..547b60fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM cyberdojo/docker-base:43587ec +FROM cyberdojo/docker-base:9f558cc LABEL maintainer=jon@jaggersoft.com RUN gem install --no-document 'concurrent-ruby' diff --git a/source/client/Dockerfile b/source/client/Dockerfile index ceea3e67..7389f1b2 100644 --- a/source/client/Dockerfile +++ b/source/client/Dockerfile @@ -1,4 +1,4 @@ -FROM cyberdojo/docker-base:43587ec +FROM cyberdojo/docker-base:9f558cc LABEL maintainer=jon@jaggersoft.com WORKDIR /runner