├── luke.png ├── entrypoint.sh ├── Makefile.patch ├── .drone.yml ├── cool.flex.patch ├── cool.y.patch ├── README.md └── Dockerfile /luke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arminfriedl/lukewarm/HEAD/luke.png -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | # Copy immutable dist to work folder if it exists and is empty 6 | if [ -d "/class" ] && [ -z "$(ls -A /class)" ]; then 7 | cp -R /usr/class/* /class/ 8 | fi 9 | 10 | exec "$@" 11 | -------------------------------------------------------------------------------- /Makefile.patch: -------------------------------------------------------------------------------- 1 | --- Makefile 2021-01-03 12:11:07.454989428 +0000 2 | +++ Makefile.work 2021-01-03 12:15:19.965132466 +0000 3 | @@ -2,7 +2,7 @@ 4 | ASSN = 4 5 | CLASS= cs143 6 | CLASSDIR= ../.. 7 | -LIB= -L/usr/pubsw/lib -lfl 8 | +LIB= -L/usr/pubsw/lib 9 | AR= gar 10 | ARCHIVE_NEW= -cr 11 | RANLIB= gar -qs 12 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | type: docker 3 | name: dirl 4 | 5 | steps: 6 | - name: publish-container 7 | image: plugins/docker 8 | settings: 9 | username: 10 | from_secret: docker_username 11 | password: 12 | from_secret: docker_password 13 | dockerfile: Dockerfile 14 | purge: true 15 | repo: arminfriedl/lukewarm 16 | tags: latest 17 | -------------------------------------------------------------------------------- /cool.flex.patch: -------------------------------------------------------------------------------- 1 | --- cool.flex 2011-06-18 03:22:02.000000000 +0000 2 | +++ cool.flex.work 2020-12-19 22:43:35.902153646 +0000 3 | @@ -12,6 +12,17 @@ 4 | #include 5 | #include 6 | 7 | +/* This is a hack to 8 | + * a) satisfy the cool compiler which expects yylex to be named cool_yylex (see below) 9 | + * b) satisfy libfl > 2.5.39 which expects a yylex symbol 10 | + * c) fix mangling errors of yylex when compiled with a c++ compiler 11 | + * d) be as non-invasive as possible to the existing assignment code 12 | + */ 13 | +extern int cool_yylex(); 14 | +extern "C" { 15 | + int (&yylex) (void) = cool_yylex; 16 | +} 17 | + 18 | /* The compiler assumes these identifiers. */ 19 | #define yylval cool_yylval 20 | #define yylex cool_yylex 21 | -------------------------------------------------------------------------------- /cool.y.patch: -------------------------------------------------------------------------------- 1 | --- cool.y 2020-12-22 01:57:18.912461835 +0000 2 | +++ cool.y.work 2020-12-22 01:57:06.089590582 +0000 3 | @@ -11,6 +11,23 @@ 4 | 5 | extern char *curr_filename; 6 | 7 | + /* This is a hack to 8 | + * a) satisfy the cool compiler which expects yylex to be named cool_yylex (see below) 9 | + * b) satisfy libfl > 2.5.39 which expects a yylex symbol 10 | + * c) fix mangling errors of yylex when compiled with a c++ compiler 11 | + * d) be as non-invasive as possible to the existing assignment code 12 | + * 13 | + * WARNING: We are now leaving standard country, but `push_macro` is supported 14 | + * in all major compilers. 15 | + */ 16 | + #pragma push_macro("yylex") 17 | + #undef yylex 18 | + int cool_yylex(); 19 | + extern "C" { 20 | + int (&yylex) (void) = cool_yylex; 21 | + } 22 | + #pragma pop_macro("yylex") 23 | + 24 | 25 | /* Locations */ 26 | #define YYLTYPE int /* the type of locations */ 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://drone.friedl.net/api/badges/container/lukewarm/status.svg)](https://drone.friedl.net/container/lukewarm) 2 | 3 | # Lukewarm and the Cool 4 | One chilly day [Cool](https://en.wikipedia.org/wiki/Cool_(programming_language)) 5 | was busy compiling yet another 6 | [fact](https://en.wikipedia.org/wiki/Cool_(programming_language)#Examples), when 7 | suddenly it became very sad. It was about its buddy 8 | [Bodhi](https://www.bodhilinux.com/). Bodhi 1.4.0 (!!) was ancient and tired. 9 | Its mirrors broke a long time ago and it just wanted to retire. 10 | 11 | Cool on the other hand was still full of verve and vim, so it went looking for a 12 | new companion. Soon enough Lukewarm entered its life. Lukewarm was a slick, 13 | quick-witted, up-to-date container and they immediately got along well. 14 | 15 | They lived happily ever after. The End. 16 | 17 | ![](luke.png) 18 | 19 | _Totally unrelated image of a cowboy from [pngwing.com](https://www.pngwing.com/en/free-png-ydaxh)_ 20 | 21 | # Uhm?! 22 | In short: If you are working through the [edX 23 | Compilers](https://www.edx.org/course/compilers) course you probably want 24 | Lukewarm instead of the Bodhi VM. It provides all the tools you need for 25 | developing your Cool compiler in an up-to-date container image. 26 | 27 | # Features 28 | Lukewarm is tailored for working through the Cool assignments. It also has 29 | several improvements over the provided [Bhodi](https://www.bodhilinux.com/) VM: 30 | - All dependencies are pre-installed 31 | - All `Cool` tools, scripts and binaries 32 | - Grading scripts are pre-installed and can be executed directly (no workarounds 33 | like in the VM) 34 | - Work locally with your favourite tools, then compile and submit from within 35 | the container 36 | - Predictable and lightweight 37 | - Use it with CI/CD 38 | - It's based on an up-to-date debian image so you can `apt-get` what you need 39 | - Tested with [podman](https://podman.io/) too 40 | 41 | # Where to get it 42 | Lukewarm is published as a container image on 43 | [https://hub.docker.com/](https://hub.docker.com/repository/docker/arminfriedl/lukewarm). 44 | You can simply run it by: 45 | 46 | ```shell 47 | docker run -it -v $PWD:/class arminfriedl/lukewarm 48 | # or 49 | podman run -it -v $PWD:/class arminfriedl/lukewarm 50 | ``` 51 | 52 | If you are using SELinux you may need to relabel the host folder so it is 53 | accessible from the container: 54 | 55 | ```shell 56 | docker run -it -v $PWD:/class:Z arminfriedl/lukewarm 57 | # or 58 | podman run -it -v $PWD:/class:Z arminfriedl/lukewarm 59 | ``` 60 | 61 | If you want to debug with gdb you will need to enable: 62 | 63 | ```shell 64 | docker run it -v $PWD:/class --cap-add=SYS_PTRACE --security-opt seccomp=unconfined arminfriedl/lukewarm 65 | # or 66 | podman run -it -v $PWD:/class --cap-add=SYS_PTRACE --security-opt seccomp=unconfined arminfriedl/lukewarm 67 | ``` 68 | 69 | You can find the repository the container image is built from on 70 | https://git.friedl.net/container/lukewarm. [Drone](https://www.drone.io/) does 71 | the heavy lifting and the build history can be found at 72 | https://drone.friedl.net/container/lukewarm. 73 | 74 | # How to use it 75 | At first start this will set up all assignments in `/class` from the [course 76 | distribution 77 | tar](https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@student-dist.tar.gz). 78 | If you mounted a host folder to `/class` you can modify the assignments on your 79 | local machine and build them in the container. 80 | 81 | The directory structure looks like this: 82 | 83 | ``` 84 | . 85 | ├── assignments 86 | │   ├── ... 87 | │   ├── PA3 88 | │   ├── PA3J 89 | │   ├── ... 90 | ├── bin 91 | ├── etc 92 | ├── examples 93 | ├── handouts 94 | ├── include 95 | ├── lib 96 | └── src 97 | ``` 98 | 99 | Edit your assignments in the `./assignments/PA[0-9]J?` folder depending on 100 | whether you want to work on the C++ or the Java version. Each `PA[0-9]J?` folder 101 | contains a `grade.pl` script. For grading and retrieving your submission code 102 | just execute `perl grade.pl` in the current assignment folder from within the 103 | Lukewarm container. 104 | 105 | # Contribute 106 | If you want to contribute to Lukewarm feel free to send patches to 107 | dev[at]friedl[dot]net. Alternatviely, you can issue a pull request on GitHub 108 | which will be cherry picked into my tree. If you plan significant long-term 109 | contributions drop me a mail for contributor access on the main tree at 110 | https://git.friedl.net/container/lukewarm. 111 | 112 | # Github Users 113 | If you are visiting this repository on GitHub, you are on a mirror of 114 | https://git.friedl.net/container/lukewarm. This mirror is regularily updated 115 | with my other GitHub mirrors. 116 | 117 | Currently I do not intend to move the main tree to GitHub. In case there is 118 | popular demand however this will change. 119 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster 2 | 3 | # Prepare image and install dependencies 4 | ENV LANG=C.UTF-8 5 | ARG DEBIAN_FRONTEND=noninteractive 6 | 7 | RUN apt-get update && apt-get install -y \ 8 | flex bison build-essential \ 9 | csh libxaw7-dev wget \ 10 | libc6-i386 default-jdk 11 | 12 | RUN mkdir -p /tmp/build 13 | COPY . /tmp/build 14 | 15 | # Install student dist 16 | 17 | # Note that this is _not_ what is in the `/usr/class/cs143` subdirectory in the 18 | # VM! The `cs143` contains make files that generate the assignments in an 19 | # arbitrary folder from skeleton files. Essentially this step was already done 20 | # in the `student-dist.tar.gz`. The assignments just have to be completed and 21 | # submitted in the respective /class/assignments/PA* subdirectories. 22 | 23 | # Prepare the immutable distribution 24 | RUN mkdir -p /usr/class \ 25 | && wget https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@student-dist.tar.gz -P /tmp \ 26 | && tar xzf "/tmp/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@student-dist.tar.gz" -C /usr/class 27 | ENV PATH=/usr/class/bin:$PATH 28 | 29 | # Download submission scripts 30 | RUN wget -O - https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@pa1-grading.pl \ 31 | | tee /usr/class/assignments/PA2J/grade.pl /usr/class/assignments/PA2/grade.pl > /dev/null 32 | 33 | RUN wget -O - https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@pa2-grading.pl \ 34 | | tee /usr/class/assignments/PA3J/grade.pl /usr/class/assignments/PA3/grade.pl > /dev/null 35 | 36 | RUN wget -O - https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@pa3-grading.pl \ 37 | | tee /usr/class/assignments/PA4J/grade.pl /usr/class/assignments/PA4/grade.pl > /dev/null 38 | 39 | RUN wget -O - https://courses.edx.org/asset-v1:StanfordOnline+SOE.YCSCS1+1T2020+type@asset+block@pa4-grading.pl \ 40 | | tee /usr/class/assignments/PA5J/grade.pl /usr/class/assignments/PA5/grade.pl > /dev/null 41 | 42 | # Download additional resources to `class/handouts`. We scrape the whole 43 | # websites every time we build the container. On the other hand they could just 44 | # provide the resources in the course ¯\_(ツ)_/¯ 45 | 46 | # Move the handouts in the student-dist.tar.gz to edx subfolder 47 | RUN mkdir -p /usr/class/handouts/edx \ 48 | && cd /usr/class/handouts \ 49 | && mv *.pdf edx 50 | 51 | # Download cs143 resources. This contains e.g. latex templates for the assignments, previous finals 52 | # https://web.stanford.edu/class/cs143/ 53 | RUN mkdir -p /usr/class/handouts/cs143 \ 54 | && cd /usr/class/handouts/cs143 \ 55 | && wget -r -k -l1 https://web.stanford.edu/class/cs143/ \ 56 | && mv web.stanford.edu/class/cs143/* . && rm -fR web.stanford.edu 57 | 58 | # Download openclassroom resources. this contains e.g. the annotated video slides. 59 | # We are downloading the directory listing from 60 | # http://openclassroom.stanford.edu/MainFolder/courses/Compilers/docs 61 | # here, so we can use mirror (-m) without parents (-np) here. 62 | # see also: http://openclassroom.stanford.edu/MainFolder/CoursePage.php?course=Compilers 63 | RUN mkdir -p /usr/class/handouts/openclassroom \ 64 | && cd /usr/class/handouts/openclassroom \ 65 | && wget -np -m http://openclassroom.stanford.edu/MainFolder/courses/Compilers/docs/ \ 66 | && mv openclassroom.stanford.edu/MainFolder/courses/Compilers/docs/* . && rm -fR openclassroom.stanford.edu 67 | 68 | # Patch tar arguments in submission scripts 69 | # We add -o to tar command since --preserve-permissions and --same-owner 70 | # are default in tar for superuser. Since we are running as root 71 | # in the container this messes up ownership of the `grading` folders 72 | # created by the `grade.pl` scripts 73 | RUN sed -i 's/-zx/-ozx/g' \ 74 | /usr/class/assignments/PA2J/grade.pl /usr/class/assignments/PA2/grade.pl \ 75 | /usr/class/assignments/PA3J/grade.pl /usr/class/assignments/PA3/grade.pl \ 76 | /usr/class/assignments/PA4J/grade.pl /usr/class/assignments/PA4/grade.pl \ 77 | /usr/class/assignments/PA5J/grade.pl /usr/class/assignments/PA5/grade.pl 78 | 79 | # Patch cool.flex, cool.y in submission folder 80 | # This is a hack to 81 | # a) satisfy the cool compiler which expects yylex to be named cool_yylex 82 | # b) satisfy libfl > 2.5.39 which expects a yylex symbol 83 | # c) fix mangling errors of yylex when compiled with a c++ compiler 84 | # d) be as non-invasive as possible to the existing assignment code 85 | RUN patch -u /usr/class/assignments/PA2/cool.flex -i /tmp/build/cool.flex.patch \ 86 | && patch -u /usr/class/assignments/PA3/cool.y -i /tmp/build/cool.y.patch \ 87 | && patch -u /usr/class/assignments/PA4/Makefile -i /tmp/build/Makefile.patch \ 88 | && patch -u /usr/class/assignments/PA5/Makefile -i /tmp/build/Makefile.patch 89 | 90 | # Setup working directory 91 | RUN mkdir -p /class 92 | WORKDIR /class 93 | 94 | # Run entrypoint to connect working directory to mounted host volume. This 95 | # copies files to the (potentially host-mounted) volume, s.t. files can be 96 | # edited on the host and are also visible in the container. 97 | COPY entrypoint.sh /usr/bin/entrypoint.sh 98 | ENTRYPOINT ["entrypoint.sh"] 99 | CMD ["/bin/bash"] 100 | --------------------------------------------------------------------------------