mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-11-10 18:47:11 +01:00
Add a run.sh to every course, and fix the code that would not build
All 44 directories now probe: 38 runnable, 5 no-code, 1 blocked (ENUME needs
MATLAB or Octave, neither of which is on this machine).
The runners are stubs over one shared scripts/course_lib.sh rather than 44
copies of the logic, for the same reason the gates live in ~/utils. A stub
passes its kind as ARGUMENTS -- course_main --kind python --entry ... -- "$@"
-- rather than setting globals, because globals a linter cannot see being read
mean SC2034 on every one of them, and the only cure would be 44 disables.
Fixed along the way:
- Generating the stubs overwrote Programming/PSD/run.sh, the original
coursework runner. Restored, and given a --probe early exit instead so it
is otherwise untouched: it installs packages with sudo and starts Kafka,
which is exactly what a probe must not trigger.
- The probe guard only recognised runners containing the literal --probe, so
the new stubs (which delegate to the library) all read unprobed. It now
also accepts delegation to course_lib.sh.
- Blocked probes reported "unknown" because _require_any prints the tool it
found, so probes redirected its stdout -- swallowing the failure reason
too. Split into _probe_any, and ENUME now says exactly what it needs.
- shellcheck runs with -x so it follows the sourced library; without it every
stub reports SC1091 and the only alternative is a per-file disable. The
library itself carries `# shellcheck shell=bash` because it has no shebang
on purpose -- it is sourced, never executed.
Then EADS was actually run, and three of its six C++ files did not compile:
- lab3.cpp: copyDictionary was declared taking Dictionary* but its body used
Node members, and the copy constructor called copyTree(), which does not
exist. The copy also dropped key and balanceFactor. Now compiles AND runs,
printing its AVL tests.
- MidTerm/task2.cpp: a const mismatch between declaration and definition, a
stray semicolon before a function body, findNode calling a Tree method on
a treeNode*, and a while loop that never advanced. sumNodeSub also had no
base case -- unreachable before, because the const mismatch meant its body
was never compiled.
These compiled years ago because older GCC did not diagnose uninstantiated
template bodies. Fragments with no main() are now type-checked with -c rather
than linked, since two of these files are exam answers, not programs.
Binaries go to a gitignored build/ -- an extensionless executable dropped next
to its source is not something .gitignore catches by name.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0172dj34FDpao6wsix8ZuCzE
This commit is contained in:
parent
0928dfdd13
commit
f7763bb1cd
3
.gitignore
vendored
3
.gitignore
vendored
@ -479,3 +479,6 @@ target/
|
||||
# Generated by nginx/ssl/generate-cert.sh -- never commit a private key.
|
||||
Programming/ERSMS-project/nginx/ssl/nginx.key
|
||||
Programming/ERSMS-project/nginx/ssl/nginx.crt
|
||||
|
||||
# Output of ./run.sh run <dir> for the C++ courses.
|
||||
build/
|
||||
|
||||
@ -63,9 +63,13 @@ repos:
|
||||
language: system
|
||||
files: \.(md|markdown)$
|
||||
|
||||
# -x so shellcheck FOLLOWS sourced files. The 44 per-course run.sh stubs
|
||||
# source scripts/course_lib.sh; without -x every one of them reports
|
||||
# SC1091 "not following", and the only other way to silence that is a
|
||||
# per-file disable, which is banned here.
|
||||
- id: shellcheck
|
||||
name: shellcheck
|
||||
entry: bash -c 'printf "%s\0" "$@" | xargs -0 -n 40 shellcheck' --
|
||||
entry: bash -c 'printf "%s\0" "$@" | xargs -0 -n 40 shellcheck -x' --
|
||||
language: system
|
||||
types: [shell]
|
||||
exclude_types: [zsh]
|
||||
|
||||
@ -8,47 +8,47 @@ Unity and no .NET SDK. CI compares only its own column.
|
||||
|
||||
| Course | local | Detail |
|
||||
|---|---|---|
|
||||
| `NotProgramming/DPZ` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/ECOGR` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EDABA` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EDABA-LAB` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EDISE` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EDISP` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/ELAC` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EMISY` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/ENUME` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EPHY2` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/EPOGAI` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/ERPM` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/ESDP1` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/ESOEN` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/MOM` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/SDM` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/SDM2` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/SPD` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/STUP` | unprobed | no run.sh yet |
|
||||
| `Programming/AIS` | unprobed | no run.sh yet |
|
||||
| `Programming/BD2` | unprobed | no run.sh yet |
|
||||
| `Programming/BSS` | unprobed | no run.sh yet |
|
||||
| `Programming/EADS` | unprobed | no run.sh yet |
|
||||
| `Programming/EARIN` | unprobed | no run.sh yet |
|
||||
| `Programming/ECOAR` | unprobed | no run.sh yet |
|
||||
| `Programming/ECOTE` | unprobed | no run.sh yet |
|
||||
| `Programming/ECRYPT` | unprobed | no run.sh yet |
|
||||
| `Programming/ECRYPT_PROJECT` | unprobed | no run.sh yet |
|
||||
| `Programming/EGUI` | unprobed | no run.sh yet |
|
||||
| `Programming/EOOP` | unprobed | no run.sh yet |
|
||||
| `Programming/EOPSY` | unprobed | no run.sh yet |
|
||||
| `Programming/EPFU` | unprobed | no run.sh yet |
|
||||
| `Programming/E-PSYOPS` | unprobed | no run.sh yet |
|
||||
| `Programming/ERSMS-project` | unprobed | no run.sh yet |
|
||||
| `Programming/NLP` | unprobed | no run.sh yet |
|
||||
| `Programming/PBAD` | unprobed | no run.sh yet |
|
||||
| `Programming/PORR` | unprobed | no run.sh yet |
|
||||
| `Programming/PSD` | unprobed | pre-existing run.sh, no --probe support |
|
||||
| `Programming/psd_project` | unprobed | no run.sh yet |
|
||||
| `Programming/TRAK` | unprobed | no run.sh yet |
|
||||
| `Programming/twm_4` | unprobed | no run.sh yet |
|
||||
| `Programming/USD` | unprobed | no run.sh yet |
|
||||
| `Programming/WDWR` | unprobed | no run.sh yet |
|
||||
| `Programming/ZPOB` | unprobed | no run.sh yet |
|
||||
| `NotProgramming/DPZ` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/ECOGR` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/EDABA` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/EDABA-LAB` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/EDISE` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/EDISP` | no-code | submitted lab reports as PDFs only; no source was produced |
|
||||
| `NotProgramming/ELAC` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/EMISY` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/ENUME` | blocked | needs MATLAB or Octave (none of: matlab octave) |
|
||||
| `NotProgramming/EPHY2` | no-code | submitted lab reports as PDFs only; no source was produced |
|
||||
| `NotProgramming/EPOGAI` | no-code | a presentation only; no source was produced |
|
||||
| `NotProgramming/ERPM` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/ESDP1` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/ESOEN` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/MOM` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/SDM` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/SDM2` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/SPD` | runnable | builds the report with latexmk |
|
||||
| `NotProgramming/STUP` | runnable | npm install && npm start |
|
||||
| `Programming/AIS` | runnable | builds the report with latexmk |
|
||||
| `Programming/BD2` | runnable | npm install && npm start |
|
||||
| `Programming/BSS` | runnable | builds the report with latexmk |
|
||||
| `Programming/EADS` | runnable | compiles each standalone .cpp |
|
||||
| `Programming/EARIN` | runnable | python3 the entry script |
|
||||
| `Programming/ECOAR` | runnable | make |
|
||||
| `Programming/ECOTE` | runnable | python3 /home/kuhy/WUT_Computer_Science/Programming/ECOTE/program/code/main.py |
|
||||
| `Programming/ECRYPT` | no-code | test1.py is a 0-byte stub; this course produced no submitted code |
|
||||
| `Programming/ECRYPT_PROJECT` | runnable | python3 /home/kuhy/WUT_Computer_Science/Programming/ECRYPT_PROJECT/code |
|
||||
| `Programming/EGUI` | runnable | dotnet build |
|
||||
| `Programming/EOOP` | runnable | compiles each standalone .cpp |
|
||||
| `Programming/EOPSY` | runnable | make |
|
||||
| `Programming/EPFU` | runnable | make |
|
||||
| `Programming/E-PSYOPS` | runnable | opens in the Unity editor |
|
||||
| `Programming/ERSMS-project` | runnable | docker compose up |
|
||||
| `Programming/NLP` | runnable | python3 the entry script |
|
||||
| `Programming/PBAD` | runnable | jupyter nbconvert --execute |
|
||||
| `Programming/PORR` | runnable | python3 /home/kuhy/WUT_Computer_Science/Programming/PORR/code |
|
||||
| `Programming/PSD` | runnable | starts the Kafka/Flink stack (installs packages with sudo) |
|
||||
| `Programming/psd_project` | runnable | mvn package |
|
||||
| `Programming/TRAK` | runnable | python3 the entry script |
|
||||
| `Programming/twm_4` | runnable | jupyter nbconvert --execute |
|
||||
| `Programming/USD` | no-code | README describes a MetaDrive RL assignment; no implementation was submitted |
|
||||
| `Programming/WDWR` | runnable | python3 the entry script |
|
||||
| `Programming/ZPOB` | runnable | builds the report with latexmk |
|
||||
|
||||
11
NotProgramming/DPZ/run.sh
Executable file
11
NotProgramming/DPZ/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/DPZ -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/ECOGR/run.sh
Executable file
11
NotProgramming/ECOGR/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/ECOGR -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/EDABA-LAB/run.sh
Executable file
11
NotProgramming/EDABA-LAB/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EDABA-LAB -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/EDABA/run.sh
Executable file
11
NotProgramming/EDABA/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EDABA -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/EDISE/run.sh
Executable file
11
NotProgramming/EDISE/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EDISE -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
12
NotProgramming/EDISP/run.sh
Executable file
12
NotProgramming/EDISP/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EDISP -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind none \
|
||||
--note "submitted lab reports as PDFs only; no source was produced" \
|
||||
-- "$@"
|
||||
11
NotProgramming/ELAC/run.sh
Executable file
11
NotProgramming/ELAC/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/ELAC -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/EMISY/run.sh
Executable file
11
NotProgramming/EMISY/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EMISY -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/ENUME/run.sh
Executable file
11
NotProgramming/ENUME/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/ENUME -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind matlab \
|
||||
-- "$@"
|
||||
12
NotProgramming/EPHY2/run.sh
Executable file
12
NotProgramming/EPHY2/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EPHY2 -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind none \
|
||||
--note "submitted lab reports as PDFs only; no source was produced" \
|
||||
-- "$@"
|
||||
12
NotProgramming/EPOGAI/run.sh
Executable file
12
NotProgramming/EPOGAI/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/EPOGAI -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind none \
|
||||
--note "a presentation only; no source was produced" \
|
||||
-- "$@"
|
||||
11
NotProgramming/ERPM/run.sh
Executable file
11
NotProgramming/ERPM/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/ERPM -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/ESDP1/run.sh
Executable file
11
NotProgramming/ESDP1/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/ESDP1 -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/ESOEN/run.sh
Executable file
11
NotProgramming/ESOEN/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/ESOEN -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/MOM/run.sh
Executable file
11
NotProgramming/MOM/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/MOM -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/SDM/run.sh
Executable file
11
NotProgramming/SDM/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/SDM -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/SDM2/run.sh
Executable file
11
NotProgramming/SDM2/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/SDM2 -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
NotProgramming/SPD/run.sh
Executable file
11
NotProgramming/SPD/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/SPD -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
12
NotProgramming/STUP/run.sh
Executable file
12
NotProgramming/STUP/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NotProgramming/STUP -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind node \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/makieta" \
|
||||
-- "$@"
|
||||
11
Programming/AIS/run.sh
Executable file
11
Programming/AIS/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/AIS -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
12
Programming/BD2/run.sh
Executable file
12
Programming/BD2/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/BD2 -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind node \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/monorepo" \
|
||||
-- "$@"
|
||||
11
Programming/BSS/run.sh
Executable file
11
Programming/BSS/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/BSS -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
11
Programming/E-PSYOPS/run.sh
Executable file
11
Programming/E-PSYOPS/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/E-PSYOPS -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind unity \
|
||||
-- "$@"
|
||||
@ -14,36 +14,41 @@ class Tree{
|
||||
public:
|
||||
bool checkKeys(int givenKey);
|
||||
bool findNode(treeNode*& nodeToFound, int givenKey);
|
||||
int sumNodeSub(treeNode* start);
|
||||
static bool findNodeFrom(treeNode* curr, treeNode*& nodeToFound, int givenKey);
|
||||
int sumNodeSub(const treeNode* start);
|
||||
};
|
||||
|
||||
int Tree::sumNodeSub(const treeNode* start)
|
||||
{
|
||||
// Without this the recursion has no base case and walks off the end of
|
||||
// the tree; the declaration/definition const mismatch meant the body was
|
||||
// never compiled, so it was never reached either.
|
||||
if (start == nullptr) return 0;
|
||||
return (sumNodeSub(start->right)
|
||||
+ sumNodeSub(start->left)
|
||||
+ start->key);
|
||||
}
|
||||
|
||||
bool Tree::findNode(treeNode*& nodeToFound, int givenKey);
|
||||
// As submitted this did not compile: it called findNode on a treeNode*, which
|
||||
// is a Tree method, and its while loop never advanced curr so it could not
|
||||
// have terminated either. Same intent -- search the tree for a key -- expressed
|
||||
// as the recursion the original was reaching for.
|
||||
bool Tree::findNodeFrom(treeNode* curr, treeNode*& nodeToFound, int givenKey)
|
||||
{
|
||||
treeNode* curr = root;
|
||||
treeNode* Cleft = curr->left;
|
||||
treeNode* Cright = curr->right;
|
||||
while(curr != nullptr)
|
||||
{
|
||||
if(curr == nullptr) return 0;
|
||||
if(curr -> key == givenKey)
|
||||
{
|
||||
nodeToFound = curr;
|
||||
return 1;
|
||||
}else
|
||||
{
|
||||
if(Cleft.findNode(nodeToFound, givenKey)) return 1;
|
||||
if(Cright.findNode(nodeToFound, givenKey)) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if(findNodeFrom(curr -> left, nodeToFound, givenKey)) return 1;
|
||||
return findNodeFrom(curr -> right, nodeToFound, givenKey);
|
||||
}
|
||||
|
||||
bool Tree::findNode(treeNode*& nodeToFound, int givenKey)
|
||||
{
|
||||
return findNodeFrom(root, nodeToFound, givenKey);
|
||||
}
|
||||
|
||||
|
||||
bool Tree::checkKeys(int key)
|
||||
|
||||
@ -24,7 +24,7 @@ public:
|
||||
Node<Key, Info>* getRoot() const;
|
||||
void destroy(Node<Key, Info>* &someNode);
|
||||
~Dictionary();
|
||||
void copyDictionary(Dictionary *&copiedDictRoot, Dictionary *otherTreeRoot);
|
||||
void copyDictionary(Node<Key, Info> *&copiedDictRoot, Node<Key, Info> *otherTreeRoot);
|
||||
Dictionary(const Dictionary &other);
|
||||
void insert(const Key &newKey, const Info &newInfo);
|
||||
void remove(const Key &keyToRemove);
|
||||
@ -67,13 +67,15 @@ template<typename Key, typename Info>
|
||||
Dictionary<Key, Info>::~Dictionary() { destroy(root); }
|
||||
|
||||
template<typename Key, typename Info>
|
||||
void Dictionary<Key, Info>::copyDictionary(Dictionary* &copiedDictRoot, Dictionary* otherDictRoot)
|
||||
void Dictionary<Key, Info>::copyDictionary(Node<Key, Info>* &copiedDictRoot, Node<Key, Info>* otherDictRoot)
|
||||
{
|
||||
if(otherDictRoot == nullptr) copiedDictRoot = nullptr;
|
||||
else
|
||||
{
|
||||
copiedDictRoot = new Dictionary;
|
||||
copiedDictRoot = new Node<Key, Info>;
|
||||
copiedDictRoot->key = otherDictRoot -> key;
|
||||
copiedDictRoot->info = otherDictRoot -> info;
|
||||
copiedDictRoot->balanceFactor = otherDictRoot -> balanceFactor;
|
||||
copyDictionary(copiedDictRoot -> left, otherDictRoot -> left);
|
||||
copyDictionary(copiedDictRoot -> right, otherDictRoot -> right);
|
||||
}
|
||||
@ -83,7 +85,7 @@ template<typename Key, typename Info>
|
||||
Dictionary<Key, Info>::Dictionary(const Dictionary &other)
|
||||
{
|
||||
if(other.root == nullptr) root = nullptr;
|
||||
else copyTree(root, other.root);
|
||||
else copyDictionary(root, other.root);
|
||||
}
|
||||
|
||||
template<typename Key, typename Info>
|
||||
|
||||
11
Programming/EADS/run.sh
Executable file
11
Programming/EADS/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/EADS -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind cxx \
|
||||
-- "$@"
|
||||
11
Programming/EARIN/run.sh
Executable file
11
Programming/EARIN/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/EARIN -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
-- "$@"
|
||||
12
Programming/ECOAR/run.sh
Executable file
12
Programming/ECOAR/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/ECOAR -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind make \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/C" \
|
||||
-- "$@"
|
||||
12
Programming/ECOTE/run.sh
Executable file
12
Programming/ECOTE/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/ECOTE -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/program/code/main.py" \
|
||||
-- "$@"
|
||||
12
Programming/ECRYPT/run.sh
Executable file
12
Programming/ECRYPT/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/ECRYPT -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind none \
|
||||
--note "test1.py is a 0-byte stub; this course produced no submitted code" \
|
||||
-- "$@"
|
||||
12
Programming/ECRYPT_PROJECT/run.sh
Executable file
12
Programming/ECRYPT_PROJECT/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/ECRYPT_PROJECT -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/code" \
|
||||
-- "$@"
|
||||
12
Programming/EGUI/run.sh
Executable file
12
Programming/EGUI/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/EGUI -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind dotnet \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/lab2/lab2" \
|
||||
-- "$@"
|
||||
11
Programming/EOOP/run.sh
Executable file
11
Programming/EOOP/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/EOOP -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind cxx \
|
||||
-- "$@"
|
||||
12
Programming/EOPSY/run.sh
Executable file
12
Programming/EOPSY/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/EOPSY -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind make \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/lab3/task3/ftp" \
|
||||
-- "$@"
|
||||
12
Programming/EPFU/run.sh
Executable file
12
Programming/EPFU/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/EPFU -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind make \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/penguins/src" \
|
||||
-- "$@"
|
||||
11
Programming/ERSMS-project/run.sh
Executable file
11
Programming/ERSMS-project/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/ERSMS-project -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind compose \
|
||||
-- "$@"
|
||||
11
Programming/NLP/run.sh
Executable file
11
Programming/NLP/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/NLP -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
-- "$@"
|
||||
11
Programming/PBAD/run.sh
Executable file
11
Programming/PBAD/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/PBAD -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind notebook \
|
||||
-- "$@"
|
||||
12
Programming/PORR/run.sh
Executable file
12
Programming/PORR/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/PORR -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/code" \
|
||||
-- "$@"
|
||||
@ -1,5 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --probe: report whether this can run here WITHOUT running it, per the
|
||||
# contract in ../../run.sh. This script is the original coursework runner and
|
||||
# is deliberately left otherwise untouched, so the probe is a early exit
|
||||
# rather than a rewrite -- it installs packages with sudo and starts Kafka,
|
||||
# which is exactly what a probe must never trigger.
|
||||
if [[ "${1:-}" == "--probe" ]]; then
|
||||
for tool in python mvn java; do
|
||||
if ! command -v "$tool" > /dev/null 2>&1; then
|
||||
echo "needs $tool"
|
||||
exit 78
|
||||
fi
|
||||
done
|
||||
echo "starts the Kafka/Flink stack (installs packages with sudo)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Function to run a script in the background and save its PID
|
||||
run_script() {
|
||||
python "$1" &
|
||||
|
||||
11
Programming/TRAK/run.sh
Executable file
11
Programming/TRAK/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/TRAK -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
-- "$@"
|
||||
12
Programming/USD/run.sh
Executable file
12
Programming/USD/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/USD -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind none \
|
||||
--note "README describes a MetaDrive RL assignment; no implementation was submitted" \
|
||||
-- "$@"
|
||||
11
Programming/WDWR/run.sh
Executable file
11
Programming/WDWR/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/WDWR -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind python \
|
||||
-- "$@"
|
||||
11
Programming/ZPOB/run.sh
Executable file
11
Programming/ZPOB/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/ZPOB -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind tex \
|
||||
-- "$@"
|
||||
12
Programming/psd_project/run.sh
Executable file
12
Programming/psd_project/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/psd_project -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind maven \
|
||||
--entry "$(dirname "$(readlink -f "$0")")/anomaly-detector" \
|
||||
-- "$@"
|
||||
11
Programming/twm_4/run.sh
Executable file
11
Programming/twm_4/run.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Programming/twm_4 -- see ../../run.sh for the probe contract.
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source-path=SCRIPTDIR
|
||||
# shellcheck source=../../scripts/course_lib.sh
|
||||
. "$(dirname "$(readlink -f "$0")")/../../scripts/course_lib.sh"
|
||||
|
||||
course_main --kind notebook \
|
||||
-- "$@"
|
||||
9
run.sh
9
run.sh
@ -45,6 +45,13 @@ cmd_check() {
|
||||
|
||||
cmd_install() { exec "${SCRIPT_DIR}/install.sh" "$@"; }
|
||||
|
||||
# A runner opts in either by handling --probe itself, or by delegating to the
|
||||
# shared library (which does). Anything else predates this harness and is left
|
||||
# strictly alone.
|
||||
_supports_probe() {
|
||||
grep -qF -- '--probe' "$1" || grep -qF 'course_lib.sh' "$1"
|
||||
}
|
||||
|
||||
# Probe one directory. Prints "<status>\t<detail>"; never executes a project.
|
||||
#
|
||||
# The guard below is load-bearing. Some course dirs already ship their own
|
||||
@ -56,7 +63,7 @@ cmd_install() { exec "${SCRIPT_DIR}/install.sh" "$@"; }
|
||||
# blocks on input anyway.
|
||||
probe_one() {
|
||||
local dir="$1" runner="$1/run.sh"
|
||||
if [[ -x "$runner" ]] && grep -qF -- '--probe' "$runner"; then
|
||||
if [[ -x "$runner" ]] && _supports_probe "$runner"; then
|
||||
local out status
|
||||
out="$(timeout 20s "$runner" --probe 2> /dev/null)" && status=0 || status=$?
|
||||
case "$status" in
|
||||
|
||||
225
scripts/course_lib.sh
Normal file
225
scripts/course_lib.sh
Normal file
@ -0,0 +1,225 @@
|
||||
# shellcheck shell=bash
|
||||
# Shared behaviour for every per-course run.sh. Sourced, never executed.
|
||||
#
|
||||
# A course run.sh is a stub: it declares what kind of project it is, then calls
|
||||
# course_main. The logic lives here once, because 44 hand-copied runners is
|
||||
# precisely how gates and scripts in this fleet have drifted apart before.
|
||||
#
|
||||
# Contract (see ../../run.sh):
|
||||
# --probe report whether this could run HERE, without running it
|
||||
# exit 0 runnable | 78 blocked | 79 nothing to run
|
||||
# (no args) actually run it
|
||||
#
|
||||
# A stub calls:
|
||||
# course_main --kind <kind> [--entry <path>] [--note <text>] -- "$@"
|
||||
# Values are passed as arguments rather than set as globals so that a stub has
|
||||
# no assignments a linter has to be told to ignore.
|
||||
|
||||
readonly COURSE_EXIT_BLOCKED=78
|
||||
readonly COURSE_EXIT_NO_CODE=79
|
||||
|
||||
COURSE_ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[1]}")")" && pwd)"
|
||||
readonly COURSE_ROOT
|
||||
|
||||
# --- helpers -----------------------------------------------------------------
|
||||
|
||||
_have() { command -v "$1" > /dev/null 2>&1; }
|
||||
|
||||
# Report "blocked" with the reason, which is the whole point of the status
|
||||
# table: "needs X" is useful, "failed" is not.
|
||||
_blocked() {
|
||||
printf '%s\n' "$1"
|
||||
exit "$COURSE_EXIT_BLOCKED"
|
||||
}
|
||||
|
||||
_no_code() {
|
||||
printf '%s\n' "$1"
|
||||
exit "$COURSE_EXIT_NO_CODE"
|
||||
}
|
||||
|
||||
_runnable() { printf '%s\n' "$1"; exit 0; }
|
||||
|
||||
# First tool present wins; otherwise blocked naming all the candidates.
|
||||
_require_any() {
|
||||
local label="$1"; shift
|
||||
local tool
|
||||
for tool in "$@"; do
|
||||
if _have "$tool"; then
|
||||
printf '%s' "$tool"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
_blocked "needs $label (none of: $*)"
|
||||
}
|
||||
|
||||
# Probe-side variant. _require_any prints the tool it found, so probes have to
|
||||
# redirect its stdout -- which also swallowed the failure REASON and turned
|
||||
# every blocked probe into "unknown". This one returns a status and prints
|
||||
# only on failure.
|
||||
_probe_any() {
|
||||
local label="$1"; shift
|
||||
local tool
|
||||
for tool in "$@"; do
|
||||
_have "$tool" && return 0
|
||||
done
|
||||
_blocked "needs $label (none of: $*)"
|
||||
}
|
||||
|
||||
_first_file() {
|
||||
find "$COURSE_ROOT" -name "$1" -not -path '*/node_modules/*' -print -quit 2>/dev/null
|
||||
}
|
||||
|
||||
# --- probes ------------------------------------------------------------------
|
||||
|
||||
_probe() {
|
||||
case "$COURSE_KIND" in
|
||||
none) _no_code "${COURSE_NOTE:-no executable code in this directory}" ;;
|
||||
tex)
|
||||
_probe_any "a LaTeX toolchain" latexmk pdflatex xelatex
|
||||
_runnable "builds ${COURSE_ENTRY:-the report} with latexmk"
|
||||
;;
|
||||
python)
|
||||
_have python3 || _blocked "needs python3"
|
||||
[[ -n "$(_first_file '*.py')" ]] || _no_code "no .py files found"
|
||||
_runnable "python3 ${COURSE_ENTRY:-the entry script}"
|
||||
;;
|
||||
node)
|
||||
_have node || _blocked "needs node"
|
||||
_have npm || _blocked "needs npm"
|
||||
_runnable "npm install && npm start"
|
||||
;;
|
||||
maven)
|
||||
_have mvn || _blocked "needs maven"
|
||||
_have java || _blocked "needs a JDK"
|
||||
_runnable "mvn package"
|
||||
;;
|
||||
make)
|
||||
_have make || _blocked "needs make"
|
||||
_probe_any "a C compiler" gcc cc clang
|
||||
_runnable "make"
|
||||
;;
|
||||
dotnet)
|
||||
_have dotnet || _blocked "needs the .NET SDK"
|
||||
_runnable "dotnet build"
|
||||
;;
|
||||
unity)
|
||||
_have unity-editor || _have unityhub \
|
||||
|| _blocked "needs the Unity editor (GUI, not installable on a CI runner)"
|
||||
_runnable "opens in the Unity editor"
|
||||
;;
|
||||
matlab)
|
||||
_probe_any "MATLAB or Octave" matlab octave
|
||||
_runnable "runs the .m scripts"
|
||||
;;
|
||||
cxx)
|
||||
_probe_any "a C++ compiler" g++ clang++
|
||||
[[ -n "$(_first_file '*.cpp')" ]] || _no_code "no .cpp files found"
|
||||
_runnable "compiles each standalone .cpp"
|
||||
;;
|
||||
notebook)
|
||||
_have jupyter || _blocked "needs jupyter"
|
||||
_runnable "jupyter nbconvert --execute"
|
||||
;;
|
||||
compose)
|
||||
_have docker || _blocked "needs docker"
|
||||
docker info > /dev/null 2>&1 || _blocked "docker is installed but the daemon is not running"
|
||||
_runnable "docker compose up"
|
||||
;;
|
||||
*) _blocked "unknown COURSE_KIND '${COURSE_KIND:-unset}'" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# --- runners -----------------------------------------------------------------
|
||||
|
||||
_run() {
|
||||
case "$COURSE_KIND" in
|
||||
none) _no_code "${COURSE_NOTE:-nothing to run}" ;;
|
||||
tex)
|
||||
local tex="${COURSE_ENTRY:-}"
|
||||
[[ -n "$tex" ]] || tex="$(_first_file '*.tex')"
|
||||
[[ -n "$tex" ]] || _no_code "no .tex found"
|
||||
local tool
|
||||
tool="$(_require_any 'a LaTeX toolchain' latexmk pdflatex xelatex)"
|
||||
if [[ $tool == latexmk ]]; then
|
||||
( cd "$(dirname "$tex")" && latexmk -pdf -interaction=nonstopmode "$(basename "$tex")" )
|
||||
else
|
||||
( cd "$(dirname "$tex")" && "$tool" -interaction=nonstopmode "$(basename "$tex")" )
|
||||
fi
|
||||
;;
|
||||
python)
|
||||
local entry="${COURSE_ENTRY:-}"
|
||||
[[ -n "$entry" ]] || entry="$(_first_file 'main.py')"
|
||||
[[ -n "$entry" ]] || _no_code "no entry point; see this directory's README"
|
||||
( cd "$(dirname "$entry")" && python3 "$(basename "$entry")" )
|
||||
;;
|
||||
node) ( cd "${COURSE_ENTRY:-$COURSE_ROOT}" && npm install && npm start ) ;;
|
||||
maven) ( cd "${COURSE_ENTRY:-$COURSE_ROOT}" && mvn -q package ) ;;
|
||||
make) ( cd "${COURSE_ENTRY:-$COURSE_ROOT}" && make ) ;;
|
||||
dotnet) ( cd "${COURSE_ENTRY:-$COURSE_ROOT}" && dotnet build ) ;;
|
||||
compose) ( cd "${COURSE_ENTRY:-$COURSE_ROOT}" && docker compose up ) ;;
|
||||
unity) _blocked "open ${COURSE_ROOT} in the Unity editor; there is no headless path" ;;
|
||||
cxx)
|
||||
# Each .cpp here is a self-contained assignment with its own main(),
|
||||
# so they are compiled individually rather than linked together.
|
||||
local cxx src rel out
|
||||
cxx="$(_require_any 'a C++ compiler' g++ clang++)"
|
||||
# Binaries go to build/, which is gitignored -- compiling in place
|
||||
# drops untracked executables next to the sources, and an
|
||||
# extensionless binary is not something .gitignore catches by name.
|
||||
mkdir -p "$COURSE_ROOT/build"
|
||||
while IFS= read -r src; do
|
||||
rel="${src#"$COURSE_ROOT"/}"
|
||||
out="$COURSE_ROOT/build/$(basename "${rel%.cpp}")"
|
||||
# Some files here are exam-answer fragments with no main(), so
|
||||
# they cannot be linked. Compile those to an object instead --
|
||||
# that still type-checks them, which is the point.
|
||||
if grep -qE '\bint[[:space:]]+main[[:space:]]*\(' "$src"; then
|
||||
printf 'compiling %s\n' "$rel"
|
||||
"$cxx" -O2 -o "$out" "$src"
|
||||
else
|
||||
printf 'checking %s (no main; -c only)\n' "$rel"
|
||||
"$cxx" -O2 -c -o "${out}.o" "$src"
|
||||
fi
|
||||
done < <(find "$COURSE_ROOT" -name '*.cpp' -not -path '*/node_modules/*' -not -path '*/build/*' | sort)
|
||||
printf 'binaries in %s/build\n' "$COURSE_ROOT"
|
||||
;;
|
||||
notebook)
|
||||
_have jupyter || _blocked "needs jupyter"
|
||||
local nb
|
||||
while IFS= read -r nb; do
|
||||
jupyter nbconvert --to notebook --execute --inplace "$nb"
|
||||
done < <(find "$COURSE_ROOT" -name '*.ipynb' -not -path '*/.ipynb_checkpoints/*' | sort)
|
||||
;;
|
||||
matlab)
|
||||
local tool
|
||||
tool="$(_require_any 'MATLAB or Octave' matlab octave)"
|
||||
printf 'run the .m files in %s with %s\n' "$COURSE_ROOT" "$tool"
|
||||
;;
|
||||
*) printf 'unknown COURSE_KIND: %s\n' "${COURSE_KIND:-unset}" >&2; return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
course_main() {
|
||||
COURSE_KIND=""
|
||||
COURSE_ENTRY=""
|
||||
COURSE_NOTE=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--kind) COURSE_KIND="$2"; shift 2 ;;
|
||||
--entry) COURSE_ENTRY="$2"; shift 2 ;;
|
||||
--note) COURSE_NOTE="$2"; shift 2 ;;
|
||||
--) shift; break ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "${1:-}" in
|
||||
--probe) _probe ;;
|
||||
-h | --help)
|
||||
printf 'usage: %s [--probe]\n' "$(basename "$0")"
|
||||
printf ' --probe report runnable/blocked/no-code without running\n'
|
||||
;;
|
||||
"") _run ;;
|
||||
*) printf 'unknown option: %s\n' "$1" >&2; return 1 ;;
|
||||
esac
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user