├── .envrc ├── .github ├── CODEOWNERS ├── dependabot.yml ├── workflows │ ├── checks.yml │ ├── build-pr.yml │ ├── build-main.yml │ └── comment-pr.yml └── settings.yml ├── LICENSE ├── .prettierrc ├── src └── thesis │ ├── imports │ ├── colors.typ │ ├── preamble.typ │ └── workarounds.typ │ ├── disclaimer.typ │ ├── theme │ ├── abstract.typ │ ├── acknowledgement.typ │ ├── colors.typ │ ├── leftblank.typ │ ├── UMONS-fs-logo.typ │ ├── UMONS-logo.typ │ ├── disclaimer.typ │ ├── definition.typ │ ├── common │ │ ├── metadata.typ │ │ └── titlepage.typ │ ├── infos.typ │ ├── UMONS-logo.svg │ ├── UMONS_FS-logo.svg │ ├── UMONS_FS.svg │ └── template.typ │ ├── extra.typ │ ├── abstract.typ │ ├── acknowledgement.typ │ ├── accessibility.typ │ └── main.typ ├── resources ├── sourcecode │ ├── bash │ │ ├── bash-diffoscope-comparison.log │ │ ├── bash-gcc-not-reproducible-builds.log │ │ └── bash-fixing-builds.log │ ├── tar-sort-name-flag.log │ ├── listing-typst-version.log │ ├── sunflowers1.log │ ├── sunflowers2.log │ ├── composer.json │ ├── nodejs.dockerfile │ ├── scenario-9-rebuild.log │ ├── datetime.c │ ├── scenario-8-diffoscope.log │ ├── date-format-flags.log │ ├── montecarlo-pi.c.log │ ├── scenario-7.log │ ├── scenario-8.log │ ├── debian-nix.log │ ├── python.dockerfile │ ├── datetime.c.log │ ├── scenario-1.log │ ├── scenario-5.log │ ├── montecarlo-pi-compilation.log │ ├── scenario-6.log │ ├── scenario-8-rebuild.log │ ├── scenario-4.log │ ├── scenario-3.log │ ├── scenario-2.log │ ├── montecarlo-pi-fix.c │ ├── montecarlo-pi.c │ ├── example-makefile │ └── nix-typst-build-diff.log ├── images │ ├── flake-vs-legacy.jpg │ ├── PXL_20230719_092843523-01.jpeg │ ├── binary.svg │ ├── circle-check.svg │ ├── note-sticky.svg │ ├── circle-exclamation.svg │ ├── circle-info.svg │ ├── quote-left.svg │ ├── quote-right.svg │ ├── lightbulb-solid.svg │ ├── highlighter-solid.svg │ ├── circle-question.svg │ ├── ORCIDiD_iconvector.svg │ ├── sourcecode.svg │ ├── build-inputs1.svg │ ├── rules.svg │ ├── inputs-cube.svg │ ├── inputs-cube-2.svg │ ├── inputs-cube-3.svg │ └── inputs-icon.svg ├── typst │ ├── reproducibility-rule.typ │ ├── inputs-and-outputs-part1.typ │ ├── inputs-and-outputs-part2.typ │ ├── inputs-and-outputs-part3.typ │ ├── inputs-computation-outputs.typ │ ├── scientific-method.typ │ ├── scientific-method-w-r13y.typ │ ├── equivalence-classes-of-reproducibility.typ │ ├── functions-vs-computations.typ │ ├── figure-checksum.typ │ ├── inputs-and-outputs-part4.typ │ ├── configuration-management-summary.typ │ ├── essawy-table.typ │ ├── my-app-graph-not-ok.typ │ ├── python-graph.typ │ ├── essawy.typ │ ├── ch4-table-conclusion.typ │ ├── ch3-table-conclusion.typ │ └── configuration-management.typ └── graphviz │ ├── scientific-method.dot │ ├── scientific-method-with-reproducibility.dot │ ├── my-app-not-ok.dot │ └── python.dot ├── .prettierignore ├── nix ├── imports │ ├── systems.nix │ ├── pkgs.nix │ ├── devshell.nix │ ├── fmt.nix │ └── typst.nix └── pkgs │ ├── weasel │ ├── package.nix │ └── weasel.sh │ ├── passive │ ├── package.nix │ └── passive.sh │ ├── dups │ ├── package.nix │ └── dups.pl │ └── sign-pdf │ └── package.nix ├── lib ├── scenario-1 │ ├── src │ │ └── datetime.c │ └── Makefile ├── scenario-2 │ ├── datetime.c │ ├── Dockerfile │ └── Makefile ├── scenario-3 │ ├── src │ │ └── datetime.c │ ├── Makefile │ └── guix.scm ├── scenario-4 │ ├── src │ │ └── datetime.c │ ├── Makefile │ └── default.nix ├── scenario-5 │ ├── src │ │ └── datetime.c │ ├── Makefile │ ├── flake.nix │ └── flake.lock ├── scenario-6 │ ├── src │ │ └── datetime.c │ ├── Makefile │ ├── flake.nix │ └── flake.lock ├── scenario-7 │ ├── Makefile │ └── src │ │ └── hello-world.typst ├── scenario-8 │ ├── Makefile │ ├── src │ │ └── hello-world.typst │ ├── flake.nix │ └── flake.lock └── scenario-9 │ ├── Makefile │ ├── src │ └── hello-world.typst │ ├── flake.nix │ └── flake.lock ├── public-key.pem ├── .gitignore ├── .editorconfig ├── .devcontainer.json ├── flake.nix ├── CITATION.cff ├── flake.lock └── README.md /.envrc: -------------------------------------------------------------------------------- 1 | use flake . 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @drupol 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC-BY-4.0 AND HL3 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "proseWrap": "always" 3 | } 4 | -------------------------------------------------------------------------------- /src/thesis/imports/colors.typ: -------------------------------------------------------------------------------- 1 | #let color-a = rgb("#990027") // #5D071D 2 | -------------------------------------------------------------------------------- /resources/sourcecode/bash/bash-diffoscope-comparison.log: -------------------------------------------------------------------------------- 1 | $ diffoscope build1 build2 2 | -------------------------------------------------------------------------------- /resources/sourcecode/tar-sort-name-flag.log: -------------------------------------------------------------------------------- 1 | $ tar --sort=name -cf archive.tar /tmp 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /.direnv/ 2 | /.idea/ 3 | /vendor/ 4 | /docs/ 5 | /build/ 6 | CHANGELOG.md 7 | -------------------------------------------------------------------------------- /resources/sourcecode/listing-typst-version.log: -------------------------------------------------------------------------------- 1 | $ typst --version 2 | typst 0.10.0 (f2433bd1) 3 | -------------------------------------------------------------------------------- /nix/imports/systems.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | ... 4 | }: 5 | { 6 | systems = import inputs.systems; 7 | } 8 | -------------------------------------------------------------------------------- /resources/images/flake-vs-legacy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drupol/master-thesis/HEAD/resources/images/flake-vs-legacy.jpg -------------------------------------------------------------------------------- /resources/sourcecode/sunflowers1.log: -------------------------------------------------------------------------------- 1 | $ nix hash path VanGogh-Sunflowers-1.jpg 2 | sha256-s7MSCem/37zgrZ1dhRdQjmq2TetV21yb41ir2Y7JcJ0= 3 | -------------------------------------------------------------------------------- /resources/sourcecode/sunflowers2.log: -------------------------------------------------------------------------------- 1 | $ nix hash path VanGogh-Sunflowers-2.jpg 2 | sha256-Iq4mipyQ1tN7NagK7g8bRH6kLnB2gVaU450OfGk5I+M= 3 | -------------------------------------------------------------------------------- /resources/images/PXL_20230719_092843523-01.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drupol/master-thesis/HEAD/resources/images/PXL_20230719_092843523-01.jpeg -------------------------------------------------------------------------------- /resources/sourcecode/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "awesome/php-library", 3 | "require": { 4 | "foo/http": "^1", 5 | "foo/bar": "1.2.3" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /resources/sourcecode/nodejs.dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine 2 | WORKDIR /app 3 | COPY . . 4 | RUN yarn install --production 5 | CMD ["node", "src/index.js"] 6 | EXPOSE 3000 7 | -------------------------------------------------------------------------------- /nix/pkgs/weasel/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | writeShellApplication, 3 | }: 4 | 5 | writeShellApplication { 6 | name = "weasel"; 7 | 8 | text = (builtins.readFile ./weasel.sh); 9 | } 10 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-9-rebuild.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-9 2 | $ nix build 3 | $ nix build --rebuild --keep-failed 4 | $ # No more error message - the build is fully reproducible now. 5 | -------------------------------------------------------------------------------- /src/thesis/disclaimer.typ: -------------------------------------------------------------------------------- 1 | #import "theme/disclaimer.typ": * 2 | 3 | #disclaimer( 4 | title: title, 5 | degree: degree, 6 | author: author, 7 | submissionDate: submissionDate, 8 | ) 9 | -------------------------------------------------------------------------------- /lib/scenario-1/src/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/scenario-2/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/scenario-3/src/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/scenario-4/src/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/scenario-5/src/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/scenario-6/src/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /nix/pkgs/passive/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | writeShellApplication, 3 | }: 4 | 5 | writeShellApplication { 6 | name = "passive"; 7 | 8 | text = (builtins.readFile ./passive.sh); 9 | } 10 | -------------------------------------------------------------------------------- /lib/scenario-1/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf datetime 3 | 4 | build: clean 5 | gcc src/datetime.c -o datetime 6 | 7 | check: 8 | nix hash path datetime 9 | 10 | run: 11 | ./datetime 12 | -------------------------------------------------------------------------------- /resources/sourcecode/datetime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf( 5 | "Built the %s at %s.\n", 6 | __DATE__, 7 | __TIME__ 8 | ); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /public-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEd4ocLaIaKaJ++bphe0y6P3sYkSAY 3 | THcRpUjAdeUHHfXeFAI8hplUBwnbr7PH9BBU4HnWMeLuwDmRe3t2Ncxhrg== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | open-pull-requests-limit: 10 8 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-8-diffoscope.log: -------------------------------------------------------------------------------- 1 | $ diffoscope /nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world \ 2 | /nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world.check 3 | -------------------------------------------------------------------------------- /nix/imports/pkgs.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | inputs.pkgs-by-name-for-flake-parts.flakeModule 5 | ]; 6 | 7 | perSystem = { 8 | pkgsDirectory = ../pkgs; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /src/thesis/theme/abstract.typ: -------------------------------------------------------------------------------- 1 | #import "common/metadata.typ": * 2 | 3 | #let abstract(title: "Abstract", body) = { 4 | pagebreak(weak: true) 5 | 6 | heading(level: 1, title, outlined: false) 7 | 8 | body 9 | } 10 | -------------------------------------------------------------------------------- /resources/sourcecode/date-format-flags.log: -------------------------------------------------------------------------------- 1 | $ date -d@2147483647 2 | Tue Jan 19 04:14:07 AM CET 2038 3 | $ date -d@2147483647 -u 4 | Tue Jan 19 03:14:07 AM UTC 2038 5 | $ LC_ALL=C date -d@2147483647 -u 6 | Tue Jan 19 03:14:07 UTC 2038 7 | -------------------------------------------------------------------------------- /resources/sourcecode/montecarlo-pi.c.log: -------------------------------------------------------------------------------- 1 | $ gcc montecarlo-pi.c -o montecarlo-pi 2 | $ ./montecarlo-pi 10 3 | 3.6 4 | $ ./montecarlo-pi 10 5 | 4 6 | $ ./montecarlo-pi 1000000 7 | 3.13989 8 | $ ./montecarlo-pi 1000000 9 | 3.14048 10 | -------------------------------------------------------------------------------- /nix/pkgs/dups/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | writeShellApplication, 3 | perl, 4 | }: 5 | 6 | writeShellApplication { 7 | name = "dups"; 8 | 9 | runtimeInputs = [ perl ]; 10 | 11 | text = '' 12 | perl ${./dups.pl} "$@" 13 | ''; 14 | } 15 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-7.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-7 2 | $ make -s build 3 | $ make -s check 4 | sha256-aOmj1feG5+7h8BDz+URLxr82DxZVrOakDR3B0ULW41c= 5 | $ make -s build 6 | $ make -s check 7 | sha256-CBeUSxEHXqHx0bsERt9cg8hO9qRR/qp2DS9/SrPTtMs= 8 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-8.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-8 2 | $ make -s build 3 | $ make -s check 4 | sha256-7c79JDFrrC+MJJd2WavQD1kCsM9wh+knRUOOdAeqMyk= 5 | $ make -s build 6 | $ make -s check 7 | sha256-aq9cxJiiRUxBqxGGV1JjR6+m2JYR7M9h/90R8GGnyxs= 8 | -------------------------------------------------------------------------------- /src/thesis/theme/acknowledgement.typ: -------------------------------------------------------------------------------- 1 | #import "common/metadata.typ": * 2 | 3 | #let acknowledgement(title: "Acknowledgements", body) = { 4 | pagebreak(weak: true) 5 | 6 | heading(level: 1, title, outlined: false) 7 | 8 | body 9 | } 10 | -------------------------------------------------------------------------------- /resources/sourcecode/debian-nix.log: -------------------------------------------------------------------------------- 1 | $ lsb_release -a 2 | Distributor ID: Debian 3 | Description: Debian GNU/Linux 12 (bookworm) 4 | Release: 12 5 | Codename: bookworm 6 | $ sudo apt-get -yq install nix 7 | $ nix --version 8 | nix (Nix) 2.8.0 9 | -------------------------------------------------------------------------------- /resources/sourcecode/python.dockerfile: -------------------------------------------------------------------------------- 1 | FROM buildpack-deps:bookworm 2 | # ... 3 | RUN set -eux; \ 4 | apt-get update; \ 5 | apt-get install -y --no-install-recommends \ 6 | libbluetooth-dev \ 7 | tk-dev \ 8 | uuid-dev \ 9 | ; \ 10 | rm -rf /var/lib/apt/lists/* 11 | # ... 12 | -------------------------------------------------------------------------------- /resources/sourcecode/bash/bash-gcc-not-reproducible-builds.log: -------------------------------------------------------------------------------- 1 | $ gcc -o build1 datetime.c 2 | $ gcc -o build2 datetime.c 3 | $ sha256sum build* 4 | 5d0b1ae966c719862971bd51b4c035a478863a409caa605b2c529d45f2ac137d build1 5 | 7cbfd989b49c7336dc495a055db223253f0c1d6dc232b66b0fe0f7b6103c274c build2 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.cache/ 2 | /.devenv/ 3 | /.direnv/ 4 | /build/ 5 | /.vscode/ 6 | /out/ 7 | *.bak* 8 | indent.log 9 | /result 10 | /*.pdf 11 | /*.pdfpc 12 | /src/**/*.pdf 13 | lib/**/output 14 | lib/**/result 15 | lib/**/*.pdf 16 | /trunk/ 17 | cert.pem 18 | private-key.pem 19 | src/thesis/literature.bib.original 20 | -------------------------------------------------------------------------------- /resources/sourcecode/bash/bash-fixing-builds.log: -------------------------------------------------------------------------------- 1 | $ export SOURCE_DATE_EPOCH=1709373544 2 | $ gcc -o build1 datetime.c 3 | $ gcc -o build2 datetime.c 4 | $ sha256sum build* 5 | 98f0419783bb3b06b45eaf5cc0efeef9408c4dad1e9eec9eb153dc7a6cc6962f build1 6 | 98f0419783bb3b06b45eaf5cc0efeef9408c4dad1e9eec9eb153dc7a6cc6962f build2 7 | -------------------------------------------------------------------------------- /lib/scenario-7/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf *.pdf 3 | 4 | build: clean 5 | docker run --entrypoint /bin/typst --mount type=bind,source="$$(pwd)"/src,target=/src ghcr.io/typst/typst:latest compile /src/hello-world.typst 6 | 7 | check: 8 | nix hash path src/hello-world.pdf 9 | 10 | run: 11 | nix hash path src/hello-world.pdf 12 | -------------------------------------------------------------------------------- /src/thesis/theme/colors.typ: -------------------------------------------------------------------------------- 1 | // Source: https://web.umons.ac.be/app/uploads/sites/8/2017/07/REF-COULEURS-FACS-UMONS.pdf 2 | #let umons-red = rgb(168, 0, 57) 3 | #let umons-turquoise = rgb(0, 171, 204) 4 | #let umons-grey = rgb(150, 150, 150) 5 | #let umons-yellow = rgb(246, 167, 35) 6 | 7 | #let umons-faculty-sciences = rgb(2, 150, 135) 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 4 5 | charset = utf-8 6 | end_of_line = lf 7 | trim_trailing_whitespace = true 8 | 9 | [Makefile] 10 | indent_style = tab 11 | 12 | [*.{tex,cls,lua,nix,typ,md}] 13 | trim_trailing_whitespace = false 14 | indent_style = space 15 | indent_size = 2 16 | max_line_length = 80 17 | -------------------------------------------------------------------------------- /resources/sourcecode/datetime.c.log: -------------------------------------------------------------------------------- 1 | $ gcc datetime.c -o datetime 2 | $ sha256sum datetime 3 | a123b...c8dba datetime 4 | $ rm datetime 5 | $ gcc datetime.c -o datetime 6 | $ sha256sum datetime 7 | 937da...1284f datetime 8 | $ ./datetime 9 | Built the Nov 21 2023 at 17:19:34. 10 | $ ./datetime 11 | Built the Nov 21 2023 at 17:19:34. 12 | -------------------------------------------------------------------------------- /src/thesis/theme/leftblank.typ: -------------------------------------------------------------------------------- 1 | #import "common/metadata.typ": * 2 | 3 | #let leftblank( 4 | weak: true, 5 | ) = { 6 | pagebreak(weak: weak) 7 | 8 | set align(center) 9 | 10 | v(80%) 11 | 12 | text(fill: black.lighten(75%))[ 13 | This page is intentionally left blank. 14 | ] 15 | 16 | pagebreak(weak: true) 17 | } 18 | -------------------------------------------------------------------------------- /lib/scenario-4/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf output result 3 | nix-collect-garbage -d 4 | 5 | build: clean 6 | nix-build 7 | 8 | check: 9 | $$(nix build --quiet --no-link --print-out-paths nixpkgs#coreutils)/bin/cp -r --dereference "$$(readlink -f result)" "output" 10 | nix hash path output 11 | chmod 777 output 12 | 13 | run: 14 | ./result/datetime 15 | -------------------------------------------------------------------------------- /lib/scenario-5/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf output result 3 | nix-collect-garbage -d 4 | 5 | build: clean 6 | nix build 7 | 8 | check: 9 | $$(nix build --quiet --no-link --print-out-paths nixpkgs#coreutils)/bin/cp -r --dereference "$$(readlink -f result)" "output" 10 | nix hash path output 11 | chmod 777 output 12 | 13 | run: 14 | ./result/datetime 15 | -------------------------------------------------------------------------------- /resources/images/binary.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.github/workflows/checks.yml: -------------------------------------------------------------------------------- 1 | name: "Nix flake check" 2 | on: 3 | workflow_call: 4 | pull_request: 5 | push: 6 | jobs: 7 | tests: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: cachix/install-nix-action@v31 12 | - run: nix flake check --accept-flake-config 13 | -------------------------------------------------------------------------------- /lib/scenario-8/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf output result 3 | nix-collect-garbage -d 4 | 5 | build: clean 6 | nix build 7 | 8 | check: 9 | $$(nix build --quiet --no-link --print-out-paths nixpkgs#coreutils)/bin/cp -r --dereference "$$(readlink -f result)" "output" 10 | nix hash path output 11 | chmod 777 output 12 | 13 | run: 14 | nix hash path output 15 | -------------------------------------------------------------------------------- /lib/scenario-9/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf output result 3 | nix-collect-garbage -d 4 | 5 | build: clean 6 | nix build 7 | 8 | check: 9 | $$(nix build --quiet --no-link --print-out-paths nixpkgs#coreutils)/bin/cp -r --dereference "$$(readlink -f result)" "output" 10 | nix hash path output 11 | chmod 777 output 12 | 13 | run: 14 | nix hash path output 15 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-1.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-1 2 | $ make -s build 3 | $ make -s check 4 | sha256-fnmArVyFozZkU/T0hrABdyq5M1kmAlUXSWvYodJm9bw= 5 | $ make -s run 6 | Built the Mar 15 2024 at 14:51:27. 7 | $ make -s build 8 | $ make -s check 9 | sha256-aFgPLDbv2BY+rCKDzsE+0fr9ylGr2R4fbWMhr4lfEQo= 10 | $ make -s run 11 | Built the Mar 15 2024 at 14:52:18. 12 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-5.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-5 2 | $ make -s build 3 | $ make -s check 4 | sha256-UiRzZFmePpkBYnAFZe9NeKRb1h1XUJ80OBxv9fRPQCQ= 5 | $ make -s run 6 | Built the Jan 1 1980 at 00:00:00. 7 | $ make -s build 8 | $ make -s check 9 | sha256-UiRzZFmePpkBYnAFZe9NeKRb1h1XUJ80OBxv9fRPQCQ= 10 | $ make -s run 11 | Built the Jan 1 1980 at 00:00:00. 12 | -------------------------------------------------------------------------------- /resources/sourcecode/montecarlo-pi-compilation.log: -------------------------------------------------------------------------------- 1 | $ gcc montecarlo-pi.c -o montecarlo-pi 2 | $ sha256sum montecarlo-pi 3 | 241d0d05314472c6472fd90814f253ccc1b4fd10366ab828201aab1ac1a0d376 montecarlo-pi 4 | $ rm montecarlo-pi 5 | $ gcc montecarlo-pi.c -o montecarlo-pi 6 | $ sha256sum montecarlo-pi 7 | 241d0d05314472c6472fd90814f253ccc1b4fd10366ab828201aab1ac1a0d376 montecarlo-pi 8 | -------------------------------------------------------------------------------- /src/thesis/theme/UMONS-fs-logo.typ: -------------------------------------------------------------------------------- 1 | #import "./common/metadata.typ": * 2 | #import "./colors.typ": * 3 | 4 | #{ 5 | set text(font: "Liberation Sans") 6 | set par(leading: 6pt) 7 | box[#image("./UMONS_FS-logo.svg", height: 60pt)] 8 | box[ 9 | #v(.7em) 10 | #text(size: .3em, fill: umons-grey)[ 11 | Faculty of\ 12 | sciences 13 | ] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /lib/scenario-3/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | 3 | build: clean 4 | guix time-machine --commit=10f3dd0e9e06d71d1bc1615c6a60cc3aa1ad1ff4 -- build -f guix.scm 5 | 6 | check: 7 | nix hash path $$(guix time-machine --commit=10f3dd0e9e06d71d1bc1615c6a60cc3aa1ad1ff4 -- build -f guix.scm) 8 | 9 | run: 10 | $$(guix time-machine --commit=10f3dd0e9e06d71d1bc1615c6a60cc3aa1ad1ff4 -- build -f guix.scm)/bin/datetime 11 | -------------------------------------------------------------------------------- /lib/scenario-6/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf output result 3 | nix-collect-garbage -d 4 | 5 | build: clean 6 | nix build 7 | gunzip -c result | docker load 8 | 9 | check: 10 | $$(nix build --quiet --no-link --print-out-paths nixpkgs#coreutils)/bin/cp -r --dereference "$$(readlink -f result)" "output" 11 | nix hash path output 12 | chmod 777 output 13 | 14 | run: 15 | docker run datetime:latest 16 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-6.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-6 2 | $ make -s build 3 | load image: datetime 4 | $ make -s check 5 | sha256-dJ3nqJW2bsnSnAca1tOivmWEbk6005mu14N3soM1xxQ= 6 | $ make -s run 7 | Built the Jan 1 1980 at 00:00:00. 8 | $ make -s build 9 | load image: datetime 10 | $ make -s check 11 | sha256-dJ3nqJW2bsnSnAca1tOivmWEbk6005mu14N3soM1xxQ= 12 | $ make -s run 13 | Built the Jan 1 1980 at 00:00:00. 14 | -------------------------------------------------------------------------------- /lib/scenario-2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b AS build-env 2 | RUN apk add --no-cache build-base=0.5-r3 3 | WORKDIR /app 4 | COPY . . 5 | RUN gcc datetime.c -o datetime 6 | 7 | FROM alpine@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b 8 | COPY --from=build-env /app/datetime /app/datetime 9 | WORKDIR /app 10 | CMD ["/app/datetime"] 11 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-8-rebuild.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-8 2 | $ nix build 3 | $ nix build --rebuild --keep-failed 4 | note: keeping build directory '/tmp/nix-build-typst-hello-world.drv-0' 5 | error: derivation '/nix/store/bsg67bk2csqbjbkib6jfqjqxyncq3l2q-typst-hello-world.drv' may not be deterministic: output '/nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world' differs from '/nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world.check' 6 | -------------------------------------------------------------------------------- /nix/pkgs/weasel/weasel.sh: -------------------------------------------------------------------------------- 1 | weasels="many|various|very|fairly|several|extremely\ 2 | |exceedingly|quite|remarkably|few|surprisingly\ 3 | |mostly|largely|huge|tiny|((are|is) a number)\ 4 | |excellent|interestingly|significantly\ 5 | |substantially|clearly|vast|relatively|completely" 6 | 7 | if [ "$1" = "" ]; then 8 | echo "usage: $(basename "$0") ..." 9 | exit 10 | fi 11 | 12 | grep -E -i -n --color "\\b($weasels)\\b" "$@" 13 | 14 | exit $? 15 | -------------------------------------------------------------------------------- /resources/typst/reproducibility-rule.typ: -------------------------------------------------------------------------------- 1 | #{ 2 | set text(font: "Virgil") 3 | image("../../resources/images/rules.svg", fit: "stretch") 4 | v(-1.5em) 5 | grid( 6 | columns: (1fr, 1fr, 1fr), 7 | { 8 | set align(left) 9 | "Not reproducible" 10 | }, 11 | { 12 | set align(center) 13 | "Partially reproducible" 14 | }, 15 | { 16 | set align(right) 17 | "Reproducible" 18 | }, 19 | ) 20 | v(2em) 21 | } 22 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-4.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-4 2 | $ make -s build 3 | /nix/store/kr0wn1hsxj0hx86ybxbqda25zza1805p-datetime 4 | $ make -s check 5 | sha256-UiRzZFmePpkBYnAFZe9NeKRb1h1XUJ80OBxv9fRPQCQ= 6 | $ make -s run 7 | Built the Jan 1 1980 at 00:00:00. 8 | $ make -s build 9 | /nix/store/kr0wn1hsxj0hx86ybxbqda25zza1805p-datetime 10 | $ make -s check 11 | sha256-UiRzZFmePpkBYnAFZe9NeKRb1h1XUJ80OBxv9fRPQCQ= 12 | $ make -s run 13 | Built the Jan 1 1980 at 00:00:00. 14 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-3.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-3 2 | $ make -s build 3 | /gnu/store/d3gnj6zakm7kwfcrzfdbjxqq41j0x3j1-datetime-1.0 4 | $ make -s check 5 | sha256-iOGz7Lg3BlQLjIi+RMCSqhL6c1UHPLg4U/W0HSQJsJA= 6 | $ make -s run 7 | Built the Jan 1 1970 at 00:00:01. 8 | $ make -s build 9 | /gnu/store/d3gnj6zakm7kwfcrzfdbjxqq41j0x3j1-datetime-1.0 10 | $ make -s check 11 | sha256-iOGz7Lg3BlQLjIi+RMCSqhL6c1UHPLg4U/W0HSQJsJA= 12 | $ make -s run 13 | Built the Jan 1 1970 at 00:00:01. 14 | -------------------------------------------------------------------------------- /lib/scenario-2/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | 3 | build: clean 4 | docker buildx build --no-cache -t datetime:latest --output type=oci,dest=image.tar . 5 | docker load -i image.tar 6 | 7 | check: 8 | docker create --quiet --name datetime datetime:latest &>/dev/null 9 | docker cp --quiet datetime:/app/datetime datetime 10 | docker container rm -f datetime &>/dev/null 11 | 12 | nix hash path datetime 13 | rm -rf datetime 14 | nix hash path image.tar 15 | 16 | run: 17 | docker run datetime:latest 18 | -------------------------------------------------------------------------------- /resources/images/circle-check.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/images/note-sticky.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nix/pkgs/sign-pdf/package.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | pkgs.writeShellApplication { 3 | name = "sign-pdf"; 4 | 5 | runtimeInputs = [ pkgs.open-pdf-sign ]; 6 | 7 | text = '' 8 | open-pdf-sign \ 9 | --certificate cert.pem \ 10 | --key private-key.pem \ 11 | --no-hint \ 12 | --timestamp \ 13 | --tsa http://timestamp.digicert.com \ 14 | --baseline-lt \ 15 | --add-page \ 16 | --page \ 17 | -1 \ 18 | --width 19 \ 19 | "$@" 20 | ''; 21 | } 22 | -------------------------------------------------------------------------------- /nix/imports/devshell.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ inputs.make-shell.flakeModules.default ]; 4 | 5 | perSystem = 6 | { 7 | pkgs, 8 | config, 9 | ... 10 | }: 11 | { 12 | make-shells.default = { 13 | packages = with pkgs; [ 14 | gnuplot 15 | tinymist 16 | typstyle 17 | config.packages.weasel 18 | config.packages.passive 19 | config.packages.dups 20 | ]; 21 | }; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /resources/images/circle-exclamation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/scenario-4/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs ? import (fetchTarball { 3 | url = "https://github.com/NixOS/nixpkgs/archive/e314d5c6d3b3a0f40ec5bcbc007b0cbe412f48ae.tar.gz"; 4 | sha256 = "049zgk55rk6x3m0v7xdcabnayc0l1rbbfvfg9fr9ky92f9g2wl12"; 5 | }) { } 6 | }: 7 | 8 | pkgs.stdenv.mkDerivation { 9 | name = "datetime"; 10 | 11 | src = ./src; 12 | 13 | buildPhase = '' 14 | $CC datetime.c -o datetime 15 | ''; 16 | 17 | installPhase = '' 18 | install -D datetime $out/bin/datetime 19 | ''; 20 | } 21 | -------------------------------------------------------------------------------- /src/thesis/imports/preamble.typ: -------------------------------------------------------------------------------- 1 | #import "@preview/diagraph:0.3.6": * 2 | #import "@preview/codly:1.3.0": * 3 | #import "@preview/codly-languages:0.1.8": * 4 | #import "@preview/glossarium:0.5.9": ( 5 | gls, glspl, make-glossary, print-glossary, register-glossary, 6 | ) 7 | #import "@preview/xarrow:0.3.1": xarrow, xarrowSquiggly, xarrowTwoHead 8 | #import "@preview/hydra:0.6.2": * 9 | #import "@preview/cetz:0.4.2" 10 | #import "@preview/cetz-plot:0.1.2": * 11 | #import "colors.typ": * 12 | #import "workarounds.typ": * 13 | -------------------------------------------------------------------------------- /resources/sourcecode/scenario-2.log: -------------------------------------------------------------------------------- 1 | $ cd lib/scenario-2 2 | $ make -s build 3 | Loaded image: datetime 4 | $ make -s check 5 | sha256-zV0YiwaUrvtHP8Xyn3wfQqkHkeRJonEI6c7BZVnEKQo= 6 | sha256-VKMisMOGn3qq3/TeGmk2NLWhU4Aez3FigY1TWiZvBOQ= 7 | $ make -s run 8 | Built the Mar 26 2024 at 13:36:07. 9 | $ make -s build 10 | Loaded image: datetime 11 | $ make -s check 12 | sha256-pY/buhRq1FZzVoMsImuWpqS0NONp7VRpinODlDIm1To= 13 | sha256-e1VCDdKYA2WMW9SKBXD/BqzDBSbCdXejLejEUx1XZi4= 14 | $ make -s run 15 | Built the Mar 26 2024 at 13:37:30. 16 | -------------------------------------------------------------------------------- /src/thesis/theme/UMONS-logo.typ: -------------------------------------------------------------------------------- 1 | #import "./common/metadata.typ": * 2 | #import "./colors.typ": * 3 | 4 | #{ 5 | set text(font: "Liberation Sans") 6 | set align(right) 7 | set par(leading: 6pt) 8 | { 9 | set text(weight: 300) 10 | upper[ 11 | #text(fill: umons-grey)[#underline( 12 | offset: 4pt, 13 | stroke: umons-red, 14 | )[U]]#text(fill: umons-red)[mons]\ 15 | ] 16 | } 17 | { 18 | set text(size: .35em, weight: 250) 19 | text(fill: umons-grey)[University of Mons] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/sourcecode/montecarlo-pi-fix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char* argv[]) { 5 | double x,y,z,count; 6 | 7 | int seed = atoi(argv[1]); // Seed for srand 8 | int n = atoi(argv[2]); // Number of iterations 9 | 10 | srand(seed); 11 | 12 | for (int i = 0; i < n; i++) { 13 | x = (double) rand() / RAND_MAX; 14 | y = (double) rand() / RAND_MAX; 15 | z = x * x + y * y; 16 | if (z <= 1) count++; 17 | } 18 | 19 | printf("π approx.: %g", (count / n) * 4); 20 | 21 | return(0); 22 | } 23 | -------------------------------------------------------------------------------- /resources/sourcecode/montecarlo-pi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char* argv[]) { 6 | double x,y,z; 7 | int count = 1; 8 | 9 | srand(time(NULL)); 10 | 11 | int n = atoi(argv[1]); // User input: number of iterations to perform 12 | 13 | for (int i = 0; i < n; i++) { 14 | x = (double) rand() / RAND_MAX; 15 | y = (double) rand() / RAND_MAX; 16 | if ((x * x + y * y) <= 1) count++; 17 | } 18 | 19 | printf("π approx.: %g\n", ((double)count / n) * 4); 20 | 21 | return(0); 22 | } 23 | -------------------------------------------------------------------------------- /resources/images/circle-info.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/typst/inputs-and-outputs-part1.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #set align(center + horizon) 4 | #set text(font: "Virgil") 5 | #grid( 6 | columns: (1fr, 1fr, 1fr, 1fr, 1fr), 7 | rows: (40pt, 25pt), 8 | image("../../resources/images/inputs-cube.svg"), 9 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 10 | image("../../resources/images/computation-cogs.svg"), 11 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 12 | image("../../resources/images/inputs-icon.svg"), 13 | 14 | "Inputs", "", "Computation", "", "Outputs", 15 | ) 16 | -------------------------------------------------------------------------------- /resources/typst/inputs-and-outputs-part2.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #set align(center + horizon) 4 | #set text(font: "Virgil") 5 | #grid( 6 | columns: (1fr, 1fr, 1fr, 1fr, 1fr), 7 | rows: (40pt, 25pt), 8 | image("../../resources/images/inputs-cube-2.svg"), 9 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 10 | image("../../resources/images/computation-cogs.svg"), 11 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 12 | image("../../resources/images/inputs-icon.svg"), 13 | 14 | "Inputs", "", "Computation", "", "Outputs", 15 | ) 16 | -------------------------------------------------------------------------------- /resources/typst/inputs-and-outputs-part3.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #set align(center + horizon) 4 | #set text(font: "Virgil") 5 | #grid( 6 | columns: (1fr, 1fr, 1fr, 1fr, 1fr), 7 | rows: (40pt, 25pt), 8 | image("../../resources/images/inputs-cube-3.svg"), 9 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 10 | image("../../resources/images/computation-cogs.svg"), 11 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 12 | image("../../resources/images/inputs-icon.svg"), 13 | 14 | "Inputs", "", "Computation", "", "Outputs", 15 | ) 16 | -------------------------------------------------------------------------------- /resources/typst/inputs-computation-outputs.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #set align(center + horizon) 4 | #set text(font: "Virgil") 5 | #grid( 6 | columns: (1fr, 1fr, 1fr, 1fr, 1fr), 7 | rows: (40pt, 25pt), 8 | image("../../resources/images/inputs-icon.svg"), 9 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 10 | image("../../resources/images/computation-cogs.svg"), 11 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 12 | image("../../resources/images/inputs-icon.svg"), 13 | 14 | "Inputs", "", "Computation", "", "Outputs", 15 | ) 16 | -------------------------------------------------------------------------------- /resources/graphviz/scientific-method.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | layout="twopi"; 3 | root = "step6"; 4 | node [shape="circle" fixedsize=true width=".8"] 5 | graph [pad=".25" nodesep="1" ranksep="1.3"] 6 | ordering="in" 7 | edge [dir="back"]; 8 | 9 | step1 -> step0 -> step5 -> step4 -> step3 -> step2 -> step1; 10 | 11 | step0 -> step6 [style=invis]; 12 | step1 -> step6 [style=invis]; 13 | step2 -> step6 [style=invis]; 14 | step3 -> step6 [style=invis]; 15 | step4 -> step6 [style=invis]; 16 | step5 -> step6 [style=invis]; 17 | step6 [style="invis"]; 18 | } 19 | -------------------------------------------------------------------------------- /resources/typst/scientific-method.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #render( 4 | read("../../resources/graphviz/scientific-method.dot"), 5 | width: 100%, 6 | labels: ( 7 | step0: [#text(font: "Virgil", size: .95em)[Observation]], 8 | step1: [#text(font: "Virgil", size: .95em)[Question]], 9 | step2: [#text(font: "Virgil", size: .95em)[Hypothesis]], 10 | step3: [#text(font: "Virgil", size: .95em)[Prediction]], 11 | step4: [#text(font: "Virgil", size: .95em)[Testing]], 12 | step5: [#text(font: "Virgil", size: .95em)[Analysis]], 13 | step6: [], 14 | ), 15 | ) 16 | -------------------------------------------------------------------------------- /src/thesis/theme/disclaimer.typ: -------------------------------------------------------------------------------- 1 | #import "common/metadata.typ": * 2 | 3 | #let disclaimer( 4 | title: "", 5 | degree: "", 6 | author: "", 7 | submissionDate: none, 8 | signature: none, 9 | ) = { 10 | pagebreak(weak: true) 11 | 12 | v(80%) 13 | text( 14 | "I confirm that this " 15 | + degree 16 | + "'s thesis is my own work and I have documented all sources and material used.", 17 | ) 18 | 19 | v(15mm) 20 | grid( 21 | columns: 2, 22 | gutter: 1fr, 23 | "Mons, " + submissionDate, 24 | { 25 | set align(right) 26 | author + signature 27 | }, 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/base:alpine", 3 | "features": { 4 | "ghcr.io/devcontainers/features/nix:1": { 5 | "extraNixConfig": "experimental-features = nix-command flakes" 6 | } 7 | }, 8 | "onCreateCommand": "nix shell nixpkgs#gitMinimal -c nix run nixpkgs#home-manager -- switch --flake git+https://code.europa.eu/ecphp/devs-profile#light --impure", 9 | "customizations": { 10 | "vscode": { 11 | "settings": { 12 | "terminal.integrated.defaultProfile.linux": "fish" 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /resources/graphviz/scientific-method-with-reproducibility.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | layout="twopi"; 3 | root = "step6"; 4 | node [shape="circle" fixedsize=true width=".8"] 5 | graph [pad=".25" nodesep="1" ranksep="1.3"] 6 | ordering="in" 7 | edge [dir="back"]; 8 | 9 | step1 -> step0 -> step5 -> step4 -> step3 -> step2 -> step1; 10 | 11 | step0 -> step6 [style=invis]; 12 | step1 -> step6 [style=invis]; 13 | step2 -> step6 [style=invis]; 14 | step3 -> step6 [style=invis]; 15 | step5 -> step6 [dir=forward penwidth=3]; 16 | step4 -> step6 [penwidth=3]; 17 | step5 -> step6 [style=invis]; 18 | 19 | step6 [penwidth=3]; 20 | } 21 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 4 | nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 5 | flake-parts.url = "github:hercules-ci/flake-parts"; 6 | systems.url = "github:nix-systems/default"; 7 | pkgs-by-name-for-flake-parts.url = "github:drupol/pkgs-by-name-for-flake-parts"; 8 | import-tree.url = "github:vic/import-tree"; 9 | make-shell.url = "github:nicknovitski/make-shell"; 10 | treefmt-nix.url = "github:numtide/treefmt-nix"; 11 | }; 12 | 13 | outputs = 14 | inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./nix/imports); 15 | } 16 | -------------------------------------------------------------------------------- /resources/images/quote-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/images/quote-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/images/lightbulb-solid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/typst/scientific-method-w-r13y.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #render( 4 | read("../../resources/graphviz/scientific-method-with-reproducibility.dot"), 5 | width: 100%, 6 | labels: ( 7 | step0: [#text(font: "Virgil", size: .95em)[Observation]], 8 | step1: [#text(font: "Virgil", size: .95em)[Question]], 9 | step2: [#text(font: "Virgil", size: .95em)[Hypothesis]], 10 | step3: [#text(font: "Virgil", size: .95em)[Prediction]], 11 | step4: [#text(font: "Virgil", size: .95em)[Testing]], 12 | step5: [#text(font: "Virgil", size: .95em)[Analysis]], 13 | step6: [#text(font: "Virgil", size: .95em)[Repeat]], 14 | ), 15 | ) 16 | -------------------------------------------------------------------------------- /lib/scenario-7/src/hello-world.typst: -------------------------------------------------------------------------------- 1 | #set page(width: 10cm, height: auto) 2 | #set heading(numbering: "1.") 3 | 4 | = Fibonacci sequence 5 | The Fibonacci sequence is defined through the 6 | recurrence relation $F_n = F_(n-1) + F_(n-2)$. 7 | It can also be expressed in _closed form:_ 8 | 9 | $ F_n = round(1 / sqrt(5) phi.alt^n), quad phi.alt = (1 + sqrt(5)) / 2 $ 10 | 11 | #let count = 8 12 | #let nums = range(1, count + 1) 13 | #let fib(n) = ( 14 | if n <= 2 { 1 } 15 | else { fib(n - 1) + fib(n - 2) } 16 | ) 17 | 18 | The first #count numbers of the sequence are: 19 | 20 | #align(center, table( 21 | columns: count, 22 | ..nums.map(n => $F_#n$), 23 | ..nums.map(n => str(fib(n))), 24 | )) 25 | -------------------------------------------------------------------------------- /lib/scenario-8/src/hello-world.typst: -------------------------------------------------------------------------------- 1 | #set page(width: 10cm, height: auto) 2 | #set heading(numbering: "1.") 3 | 4 | = Fibonacci sequence 5 | The Fibonacci sequence is defined through the 6 | recurrence relation $F_n = F_(n-1) + F_(n-2)$. 7 | It can also be expressed in _closed form:_ 8 | 9 | $ F_n = round(1 / sqrt(5) phi.alt^n), quad phi.alt = (1 + sqrt(5)) / 2 $ 10 | 11 | #let count = 8 12 | #let nums = range(1, count + 1) 13 | #let fib(n) = ( 14 | if n <= 2 { 1 } 15 | else { fib(n - 1) + fib(n - 2) } 16 | ) 17 | 18 | The first #count numbers of the sequence are: 19 | 20 | #align(center, table( 21 | columns: count, 22 | ..nums.map(n => $F_#n$), 23 | ..nums.map(n => str(fib(n))), 24 | )) 25 | -------------------------------------------------------------------------------- /resources/typst/equivalence-classes-of-reproducibility.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #table( 4 | columns: (1fr, 1fr), 5 | align: left + horizon, 6 | stroke: none, 7 | table.header( 8 | [*Equivalence class*], 9 | table.vline(stroke: .5pt), 10 | [*Examples*], 11 | table.hline(stroke: .5pt), 12 | ), 13 | [Same phenomenon], 14 | [Human experts], 15 | table.hline(stroke: .5pt), 16 | [Same statistics], 17 | [Software like GNUplot, Matplotlib, R], 18 | table.hline(stroke: .5pt), 19 | [Same data], 20 | [Checksum of file contents], 21 | table.hline(stroke: .5pt), 22 | [Same bits], 23 | [Checksum of file contents and metadata], 24 | ) 25 | -------------------------------------------------------------------------------- /resources/images/highlighter-solid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/scenario-9/src/hello-world.typst: -------------------------------------------------------------------------------- 1 | #set document(date: none) 2 | #set page(width: 10cm, height: auto) 3 | #set heading(numbering: "1.") 4 | 5 | = Fibonacci sequence 6 | The Fibonacci sequence is defined through the 7 | recurrence relation $F_n = F_(n-1) + F_(n-2)$. 8 | It can also be expressed in _closed form:_ 9 | 10 | $ F_n = round(1 / sqrt(5) phi.alt^n), quad phi.alt = (1 + sqrt(5)) / 2 $ 11 | 12 | #let count = 8 13 | #let nums = range(1, count + 1) 14 | #let fib(n) = ( 15 | if n <= 2 { 1 } 16 | else { fib(n - 1) + fib(n - 2) } 17 | ) 18 | 19 | The first #count numbers of the sequence are: 20 | 21 | #align(center, table( 22 | columns: count, 23 | ..nums.map(n => $F_#n$), 24 | ..nums.map(n => str(fib(n))), 25 | )) 26 | -------------------------------------------------------------------------------- /resources/typst/functions-vs-computations.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #table( 4 | columns: (2fr, 3fr, 5fr), 5 | stroke: none, 6 | align: left + top, 7 | table.header( 8 | [], 9 | table.vline(stroke: .5pt), 10 | [*Theoretically*], 11 | table.vline(stroke: .5pt), 12 | [*Practically*], 13 | table.hline(stroke: .5pt), 14 | ), 15 | [*Function*], 16 | [$I -> R$], 17 | [ 18 | $"eval"(F,I,emptyset) -> R$ 19 | ], 20 | table.hline(stroke: .5pt), 21 | [*Computation*], 22 | [$I times E -> R$], 23 | [ 24 | $"eval"(F,I,E) -> R$\ 25 | 26 | Reproducible if and only if\ 27 | $forall e_1,e_2 in E quad "eval"(F,I,e_1) = "eval"(F,I,e_2)$ 28 | ], 29 | ) 30 | -------------------------------------------------------------------------------- /lib/scenario-5/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 | flake-parts.url = "github:hercules-ci/flake-parts"; 5 | }; 6 | 7 | outputs = inputs @ { flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { 8 | systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ]; 9 | 10 | perSystem = { pkgs, ... }: { 11 | packages.default = pkgs.stdenv.mkDerivation { 12 | name = "datetime"; 13 | 14 | src = ./src; 15 | 16 | buildPhase = '' 17 | $CC datetime.c -o datetime 18 | ''; 19 | 20 | installPhase = '' 21 | install -D datetime $out/bin/datetime 22 | ''; 23 | }; 24 | }; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /resources/images/circle-question.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/sourcecode/example-makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | # This `clean` step is a dependency of the build step 3 | # It will remove the files and artefacts generated by the `build` step 4 | rm -rf test.txt 5 | 6 | build: clean 7 | # This `build` step will compile the source code and generate the 8 | # output artefacts. 9 | # It has a dependency on the `clean` step 10 | echo "hello world" > test.txt 11 | 12 | check: 13 | # This `check` step will print the checksum of the output artefacts 14 | sha256sum test.txt 15 | 16 | run: 17 | # This `run` step will execute the output artefacts and print the result 18 | # In case of a non-executable output, it will print the content of the # file or its checksum. 19 | cat test.txt 20 | -------------------------------------------------------------------------------- /lib/scenario-8/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 | flake-parts.url = "github:hercules-ci/flake-parts"; 5 | }; 6 | 7 | outputs = inputs @ { flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { 8 | systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ]; 9 | 10 | perSystem = { pkgs, ... }: { 11 | packages.default = pkgs.stdenv.mkDerivation { 12 | name = "typst-hello-world"; 13 | 14 | src = ./src; 15 | 16 | nativeBuildInputs = [ pkgs.typst ]; 17 | 18 | buildPhase = '' 19 | typst compile hello-world.typst hello-world.pdf 20 | ''; 21 | 22 | installPhase = '' 23 | install -D hello-world.pdf $out/hello-world.pdf 24 | ''; 25 | }; 26 | }; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /lib/scenario-9/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 | flake-parts.url = "github:hercules-ci/flake-parts"; 5 | }; 6 | 7 | outputs = inputs @ { flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { 8 | systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ]; 9 | 10 | perSystem = { pkgs, ... }: { 11 | packages.default = pkgs.stdenv.mkDerivation { 12 | name = "typst-hello-world"; 13 | 14 | src = ./src; 15 | 16 | nativeBuildInputs = [ pkgs.typst ]; 17 | 18 | buildPhase = '' 19 | typst compile hello-world.typst hello-world.pdf 20 | ''; 21 | 22 | installPhase = '' 23 | install -D hello-world.pdf $out/hello-world.pdf 24 | ''; 25 | }; 26 | }; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/thesis/theme/definition.typ: -------------------------------------------------------------------------------- 1 | #import "infos.typ": * 2 | #import "common/metadata.typ": * 3 | 4 | #let definition(term: none, name: none, content) = { 5 | let kind = "Definition" 6 | let supplement = upper(kind.first()) + lower(kind.slice(1)) 7 | let name = if name == none { 8 | "def-" + term 9 | } else { 10 | name 11 | } 12 | 13 | show figure.where(kind: "definition"): it => info-box( 14 | kind: "definition", 15 | settings: (prefix: [#smallcaps[#it.caption]]), 16 | )[ 17 | #it.body 18 | ] 19 | show figure.caption.where(kind: "definition"): it => block(width: 100%, { 20 | it 21 | }) 22 | 23 | [ 24 | #figure( 25 | kind: "definition", 26 | supplement: [#supplement], 27 | caption: term, 28 | numbering: "1", 29 | content, 30 | ) #label(name) 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /resources/typst/figure-checksum.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #{ 4 | set align(center + horizon) 5 | set text(font: "Virgil") 6 | grid( 7 | columns: (1fr, 1fr, 1fr, 1fr, 1fr), 8 | rows: (40pt, 25pt), 9 | image("../../resources/images/inputs-icon.svg"), 10 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 11 | image("../../resources/images/computation-cogs.svg"), 12 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 13 | { 14 | set text( 15 | font: "Liberation Mono", 16 | size: .7em, 17 | ) 18 | box(inset: 10pt, fill: luma(230), width: 100pt, stroke: 1pt, radius: 5pt)[ 19 | 2aae6c35c9\ 20 | 4fcfb415db\ 21 | e95f408b9c\ 22 | e91ee846ed 23 | ] 24 | }, 25 | 26 | "Inputs", "", "Checksum", "", "Outputs", 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: Reproducibility in Software Engineering 3 | authors: 4 | - given-names: Pol 5 | family-names: Dellaiera 6 | email: pol.dellaiera@protonmail.com 7 | orcid: 'https://orcid.org/0009-0008-7972-7160' 8 | url: "https://codeberg.org/p1ld7a/master-thesis" 9 | repository-code: 'https://codeberg.org/p1ld7a/master-thesis' 10 | doi: 10.5281/zenodo.12666898 11 | date-released: 2024-07-01 12 | keywords: 13 | - reproducibility 14 | - software engineering 15 | preferred-citation: 16 | type: thesis 17 | thesis-type: Msc 18 | department: "Faculty Of Sciences" 19 | authors: 20 | - family-names: "Dellaiera" 21 | given-names: "Pol" 22 | orcid: "https://orcid.org/0009-0008-7972-7160" 23 | institution: 24 | - name: "University Of Mons" 25 | city: Mons 26 | country: BE 27 | doi: "10.5281/zenodo.12666898" 28 | month: 6 29 | title: "Reproducibility in Software Engineering" 30 | year: 2024 31 | -------------------------------------------------------------------------------- /lib/scenario-3/guix.scm: -------------------------------------------------------------------------------- 1 | (use-modules (guix) 2 | (guix build-system gnu)) 3 | 4 | (define-public datetime 5 | (package 6 | (name "datetime") 7 | (version "1.0") 8 | (source (local-file "./src" #:recursive? #t)) 9 | (build-system gnu-build-system) 10 | (arguments 11 | '( 12 | #:tests? #f 13 | #:phases 14 | (modify-phases %standard-phases 15 | (delete 'configure) 16 | (replace 'build 17 | (lambda _ (invoke "gcc" "datetime.c" "-o" "datetime"))) 18 | (replace 'install 19 | (lambda* (#:key outputs #:allow-other-keys) 20 | (let ((out (assoc-ref outputs "out"))) 21 | (install-file "datetime" (string-append out "/bin")))))))) 22 | (synopsis "DateTime Program") 23 | (description "This package contains a simple program that shows the current date and time.") 24 | (home-page #f) 25 | (license #f))) 26 | 27 | datetime 28 | -------------------------------------------------------------------------------- /resources/images/ORCIDiD_iconvector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /lib/scenario-6/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 | flake-parts.url = "github:hercules-ci/flake-parts"; 5 | }; 6 | 7 | outputs = inputs @ { flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { 8 | systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ]; 9 | 10 | perSystem = { pkgs, ... }: { 11 | packages.default = 12 | let 13 | datetime = pkgs.stdenv.mkDerivation { 14 | name = "datetime"; 15 | 16 | src = ./src; 17 | 18 | buildPhase = '' 19 | $CC datetime.c -o datetime 20 | ''; 21 | 22 | installPhase = '' 23 | install -D datetime $out/bin/datetime 24 | ''; 25 | }; 26 | in 27 | pkgs.dockerTools.buildLayeredImage { 28 | name = "datetime"; 29 | tag = "latest"; 30 | contents = [ datetime ]; 31 | config.Cmd = [ "/datetime" ]; 32 | }; 33 | }; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /nix/pkgs/dups/dups.pl: -------------------------------------------------------------------------------- 1 | # Finds duplicate adjacent words. 2 | 3 | use strict ; 4 | 5 | my $DupCount = 0 ; 6 | 7 | if (!@ARGV) { 8 | print "usage: dups ...\n" ; 9 | exit ; 10 | } 11 | 12 | while (1) { 13 | my $FileName = shift @ARGV ; 14 | 15 | # Exit code = number of duplicates found. 16 | exit $DupCount if (!$FileName) ; 17 | 18 | open FILE, $FileName or die $!; 19 | 20 | my $LastWord = "" ; 21 | my $LineNum = 0 ; 22 | 23 | while () { 24 | chomp ; 25 | 26 | $LineNum ++ ; 27 | 28 | my @words = split (/(\W+)/) ; 29 | 30 | foreach my $word (@words) { 31 | # Skip spaces: 32 | next if $word =~ /^\s*$/ ; 33 | 34 | # Skip punctuation: 35 | if ($word =~ /^\W+$/) { 36 | $LastWord = "" ; 37 | next ; 38 | } 39 | 40 | # Found a dup? 41 | if (lc($word) eq lc($LastWord)) { 42 | print "$FileName:$LineNum $word\n" ; 43 | $DupCount ++ ; 44 | } # Thanks to Sean Cronin for tip on case. 45 | 46 | # Mark this as the last word: 47 | $LastWord = $word ; 48 | } 49 | } 50 | 51 | close FILE ; 52 | } 53 | -------------------------------------------------------------------------------- /resources/images/sourcecode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/typst/inputs-and-outputs-part4.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | #import "../../src/thesis/theme/colors.typ": * 3 | 4 | #set align(center + horizon) 5 | #set text(font: "Virgil") 6 | #grid( 7 | columns: (1fr, 1fr, 1fr, 1fr, 1fr), 8 | rows: (70pt, 25pt), 9 | { 10 | place(top + left, dx: 15pt, dy: 9pt)[#text(fill: umons-red)[Program]] 11 | place( 12 | top + left, 13 | dx: 15pt, 14 | dy: 31pt, 15 | )[#text(fill: umons-turquoise)[Parameters]] 16 | place(top + left, dx: 15pt, dy: 53pt)[#text(fill: umons-grey)[Environment]] 17 | image("../../resources/images/build-inputs1.svg") 18 | }, 19 | { 20 | xarrow(sym: sym.arrow.r, width: 50pt, "") 21 | xarrow(sym: sym.arrow.r, width: 50pt, "") 22 | xarrow(sym: sym.arrow.r, width: 50pt, "") 23 | }, 24 | { 25 | place(top + left, dx: 35pt, dy: 38pt)[#text(size: .75em)[Evaluation]] 26 | image("../../resources/images/build-inputs2.svg") 27 | }, 28 | xarrow(sym: sym.arrow.r, width: 50pt, ""), 29 | image("../../resources/images/inputs-icon.svg"), 30 | 31 | "Inputs", "", "Computational environment", "", "Outputs", 32 | ) 33 | -------------------------------------------------------------------------------- /resources/typst/configuration-management-summary.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #set align(left) 4 | 5 | #table( 6 | columns: (auto, 1fr, 1fr), 7 | stroke: none, 8 | table.header( 9 | [], 10 | table.vline(stroke: 1pt), 11 | [#align(center)[*Imperative*]], 12 | table.vline(stroke: .5pt), 13 | [#align(center)[*Declarative*]], 14 | table.hline(stroke: 1pt), 15 | ), 16 | table.cell(align: horizon + center)[*Divergent*], 17 | table.hline(stroke: .5pt), 18 | [ 19 | - Shell commands 20 | ], 21 | [], 22 | table.cell(align: horizon + center)[*Convergent*], 23 | table.hline(stroke: .5pt), 24 | [ 25 | - Ansible #cite(, form: "normal") 26 | - Chef #cite(, form: "normal") 27 | - Docker #cite(, form: "normal") 28 | ], 29 | [ 30 | - Puppet #cite(, form: "normal") 31 | - Terraform #cite(, form: "normal") 32 | ], 33 | table.hline(stroke: .5pt), 34 | table.cell(align: horizon + center)[*Congruent*], 35 | [], 36 | [ 37 | - Guix #cite(, form: "normal") 38 | - Nix #cite(, form: "normal") 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /resources/typst/essawy-table.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | #import table: cell, header 3 | 4 | #{ 5 | table( 6 | columns: 7, 7 | align: (right,) + (center,) * 2, 8 | stroke: none, 9 | table.header( 10 | cell(rowspan: 2)[], 11 | table.vline(stroke: .5pt), 12 | cell(colspan: 3)[*Original*], 13 | table.vline(stroke: .5pt), 14 | cell(colspan: 3)[*Other*], 15 | [*researcher*], 16 | [*machine*], 17 | [*data*], 18 | [*researcher*], 19 | [*machine*], 20 | [*data*], 21 | table.hline(stroke: .5pt), 22 | ), 23 | [*Repeatability*], 24 | [\u{2713}], 25 | [\u{2713}], 26 | [\u{2713}], 27 | [], 28 | [], 29 | [], 30 | table.hline(stroke: .5pt + black.lighten(75%)), 31 | [*Runnability*], 32 | [\u{2713}], 33 | [], 34 | [\u{2713}], 35 | [], 36 | [\u{2713}], 37 | [], 38 | table.hline(stroke: .5pt + black.lighten(75%)), 39 | [*Reproducibility*], 40 | [], 41 | [], 42 | [\u{2713}], 43 | [\u{2713}], 44 | [\u{2713}], 45 | [], 46 | table.hline(stroke: .5pt + black.lighten(75%)), 47 | [*Replicability*], 48 | [], 49 | [], 50 | [], 51 | [\u{2713}], 52 | [\u{2713}], 53 | [\u{2713}], 54 | ) 55 | } 56 | -------------------------------------------------------------------------------- /resources/images/build-inputs1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/thesis/extra.typ: -------------------------------------------------------------------------------- 1 | #import "imports/preamble.typ": * 2 | 3 | #heading("Open Source", level: 1, outlined: false) 4 | 5 | This master thesis has been developed exclusively using open-source tools. 6 | Similar to an open-source project, it was maintained in a private `git` 7 | repository #cite(, form: "normal"). That repository will be made 8 | public after the oral defense and necessary internal cleanup. Automated and 9 | reproducible builds were managed via GitHub Actions 10 | #cite(, form: "normal"), ensuring that a new compiled version was 11 | published at each commit to the project. Additionally, I'm planning to publish 12 | it on Zenodo #cite(, form: "normal") after the necessary formalities are 13 | completed. 14 | 15 | This work is licenced under a dual license: the #gls("CC BY 4.0") and the 16 | #gls("HL3") licences. You are free to share and adapt the material under the 17 | terms of the `CC BY 4.0`, provided you give appropriate credit to the original 18 | author. You must also use the material in accordance with the ethical guidelines 19 | specified in `HL3`, ensuring it is not used to contribute to human rights abuses 20 | or other unethical practices. In case of any conflict between the licences, 21 | `HL3` will take precedence. 22 | 23 | For the purpose of the @chapter3, an open-source project 24 | #cite(, form: "normal") was created to provide a full 25 | transparency on the results shown in that chapter. 26 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/probot/settings 2 | 3 | branches: 4 | - name: main 5 | protection: 6 | enforce_admins: false 7 | required_pull_request_reviews: 8 | dismiss_stale_reviews: true 9 | require_code_owner_reviews: true 10 | required_approving_review_count: 1 11 | restrictions: null 12 | required_linear_history: true 13 | - name: update_flake_lock_action 14 | protection: 15 | enforce_admins: false 16 | required_pull_request_reviews: 17 | dismiss_stale_reviews: true 18 | require_code_owner_reviews: false 19 | restrictions: null 20 | required_linear_history: true 21 | 22 | labels: 23 | - name: bug 24 | color: ee0701 25 | 26 | - name: dependencies 27 | color: 0366d6 28 | 29 | - name: enhancement 30 | color: 0e8a16 31 | 32 | - name: question 33 | color: cc317c 34 | 35 | - name: security 36 | color: ee0701 37 | 38 | - name: stale 39 | color: eeeeee 40 | 41 | repository: 42 | allow_merge_commit: true 43 | allow_rebase_merge: true 44 | allow_squash_merge: true 45 | default_branch: main 46 | description: 47 | "Pol Dellaiera's Master Thesis - Reproducibility In Software Engineering" 48 | homepage: https://codeberg.org/p1ld7a/master-thesis 49 | topics: master-thesis,umons 50 | has_downloads: true 51 | has_issues: true 52 | has_pages: false 53 | has_projects: false 54 | has_wiki: false 55 | name: master-thesis 56 | private: false 57 | -------------------------------------------------------------------------------- /nix/imports/fmt.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ inputs.treefmt-nix.flakeModule ]; 4 | 5 | perSystem = 6 | { pkgs, lib, ... }: 7 | { 8 | treefmt = { 9 | projectRootFile = "flake.nix"; 10 | programs = { 11 | deadnix.enable = true; 12 | nixfmt.enable = true; 13 | prettier.enable = true; 14 | shfmt.enable = true; 15 | shellcheck.enable = true; 16 | typstyle.enable = true; 17 | }; 18 | settings = { 19 | formatter = { 20 | bibtex-tidy = { 21 | command = "${lib.getExe pkgs.bibtex-tidy}"; 22 | includes = [ "*.bib" ]; 23 | }; 24 | }; 25 | on-unmatched = "fatal"; 26 | global.excludes = [ 27 | ".editorconfig" 28 | ".prettierrc" 29 | "LICENSE" 30 | "tests/lib/bashunit" 31 | ".prettierignore" 32 | ".shellcheckrc" 33 | "*.pdf" 34 | "*.png" 35 | "*.pem" 36 | "*.key" 37 | ".envrc" 38 | ".github/CODEOWNERS" 39 | "CITATION.cff" 40 | "lib/**" 41 | "*.pl" 42 | "*.dot" 43 | "*.svg" 44 | "*.jpeg" 45 | "*.jpg" 46 | "*.log" 47 | "*.c" 48 | "resources/sourcecode/example-makefile" 49 | "*.dockerfile" 50 | "nix/pkgs/passive/passive.sh" 51 | "nix/pkgs/weasel/weasel.sh" 52 | "*.original" 53 | ]; 54 | }; 55 | }; 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /src/thesis/abstract.typ: -------------------------------------------------------------------------------- 1 | #import "theme/abstract.typ": * 2 | 3 | #abstract[ 4 | The concept of reproducibility has long been a cornerstone in scientific 5 | research, ensuring that results are robust, repeatable, and can be 6 | independently verified. This concept has been extended to computer science, 7 | focusing on the ability to recreate identical software artefacts. However, the 8 | importance of reproducibility in software engineering is often overlooked, 9 | leading to challenges in the validation, security, and reliability of software 10 | products. 11 | 12 | This master's thesis aims to investigate the current state of reproducibility 13 | in software engineering, exploring both the barriers and potential solutions 14 | to making software more reproducible and raising awareness. It identifies key 15 | factors that impede reproducibility such as inconsistent environments, lack of 16 | standardisation, and incomplete documentation. To tackle these issues, I 17 | propose an empirical comparison of tools facilitating software 18 | reproducibility. 19 | 20 | To provide a comprehensive assessment of reproducibility in software 21 | engineering, this study adopts a methodology that involves a hands-on 22 | evaluation of four different methods and tools. Through a systematic 23 | evaluation of these tools, this research seeks to determine their 24 | effectiveness in establishing and maintaining identical software environments 25 | and builds. 26 | 27 | This study contributes to academic knowledge and offers practical insights 28 | that could influence future software development protocols and standards. 29 | ] 30 | -------------------------------------------------------------------------------- /nix/pkgs/passive/passive.sh: -------------------------------------------------------------------------------- 1 | irregulars="awoken|\ 2 | been|born|beat|\ 3 | become|begun|bent|\ 4 | beset|bet|bid|\ 5 | bidden|bound|bitten|\ 6 | bled|blown|broken|\ 7 | bred|brought|broadcast|\ 8 | built|burnt|burst|\ 9 | bought|cast|caught|\ 10 | chosen|clung|come|\ 11 | cost|crept|cut|\ 12 | dealt|dug|dived|\ 13 | done|drawn|dreamt|\ 14 | driven|drunk|eaten|fallen|\ 15 | fed|felt|fought|found|\ 16 | fit|fled|flung|flown|\ 17 | forbidden|forgotten|\ 18 | foregone|forgiven|\ 19 | forsaken|frozen|\ 20 | gotten|given|gone|\ 21 | ground|grown|hung|\ 22 | heard|hidden|hit|\ 23 | held|hurt|kept|knelt|\ 24 | knit|known|laid|led|\ 25 | leapt|learnt|left|\ 26 | lent|let|lain|lighted|\ 27 | lost|made|meant|met|\ 28 | misspelt|mistaken|mown|\ 29 | overcome|overdone|overtaken|\ 30 | overthrown|paid|pled|proven|\ 31 | put|quit|read|rid|ridden|\ 32 | rung|risen|run|sawn|said|\ 33 | seen|sought|sold|sent|\ 34 | set|sewn|shaken|shaven|\ 35 | shorn|shed|shone|shod|\ 36 | shot|shown|shrunk|shut|\ 37 | sung|sunk|sat|slept|\ 38 | slain|slid|slung|slit|\ 39 | smitten|sown|spoken|sped|\ 40 | spent|spilt|spun|spit|\ 41 | split|spread|sprung|stood|\ 42 | stolen|stuck|stung|stunk|\ 43 | stridden|struck|strung|\ 44 | striven|sworn|swept|\ 45 | swollen|swum|swung|taken|\ 46 | taught|torn|told|thought|\ 47 | thrived|thrown|thrust|\ 48 | trodden|understood|upheld|\ 49 | upset|woken|worn|woven|\ 50 | wed|wept|wound|won|\ 51 | withheld|withstood|wrung|\ 52 | written" 53 | 54 | if [ "$1" = "" ]; then 55 | echo "usage: $(basename "$0") ..." 56 | exit 57 | fi 58 | 59 | grep -E -n -i --color \ 60 | "\\b(am|are|were|being|is|been|was|be)\ 61 | \\b[ ]*(\w+ed|($irregulars))\\b" "$@" 62 | 63 | exit $? 64 | -------------------------------------------------------------------------------- /resources/typst/my-app-graph-not-ok.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #{ 4 | set text( 5 | font: "Inconsolata Nerd Font Mono", 6 | size: 1em, 7 | ) 8 | render( 9 | read("../../resources/graphviz/my-app-not-ok.dot"), 10 | width: 100%, 11 | labels: ( 12 | "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12": [my-app-1.2.3], 13 | "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8": [bzip2-1.0.8], 14 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4": [ncurses-6.4], 15 | "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1": [sqlite-3.43.1], 16 | "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1": [readline-8.2p1], 17 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3": [xz-5.6.1], 18 | "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23": [gdbm-1.23], 19 | "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10": [openssl-3.0.10], 20 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8": [glibc-2.37-8], 21 | "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4": [libidn2-2.3.4], 22 | "br1p5pan2pgmgrm81kj43qawd9b9nns1-libunistring-1.1": [libunistring-1.1], 23 | "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36": [libxcrypt-4.4.36], 24 | "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0": [expat-2.5.0], 25 | "rfckdjskd983ylf05jm9mlsw7y618hyr-xgcc-12.3.0-libgcc": [xgcc-12.3.0-libgcc], 26 | "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4": [zlib-1.3], 27 | "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15": [bash-5.2-p15], 28 | "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib": [gcc-12.3.0-lib], 29 | "xvxaw8q1b4dja27ljmynmc9818aagjz3-gcc-12.3.0-libgcc": [gcc-12.3.0-libgcc], 30 | "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4": [libffi-3.4.4], 31 | ), 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/build-pr.yml: -------------------------------------------------------------------------------- 1 | name: Build PR 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | build: 9 | name: Build PDF files 10 | runs-on: ubuntu-latest 11 | if: github.ref != 'refs/heads/main' 12 | 13 | steps: 14 | - name: Set git to use LF 15 | run: | 16 | git config --global core.autocrlf false 17 | git config --global core.eol lf 18 | 19 | - name: Check out source files 20 | uses: actions/checkout@v4 21 | 22 | - name: Install Nix 23 | uses: cachix/install-nix-action@v31 24 | 25 | - name: Extract branch name 26 | shell: bash 27 | run: 28 | echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> 29 | $GITHUB_OUTPUT 30 | id: extract_branch 31 | 32 | - name: Build document 33 | run: | 34 | nix build .#thesis --out-link result-thesis --quiet 35 | cp -vr --dereference $(readlink -f result-thesis) thesis 36 | mkdir -p artefacts 37 | cp -ar thesis/* artefacts/ 38 | 39 | - name: Rename files 40 | working-directory: artefacts 41 | run: | 42 | for f in *.pdf; do mv ${f} $(printf '%s\n' "${{ github.run_number }}--${f%.pdf}--${{ github.sha }}.pdf"); done 43 | 44 | - name: Upload build assets 45 | uses: actions/upload-artifact@v5 46 | with: 47 | name: 48 | pdf--branch-${{ steps.extract_branch.outputs.branch 49 | }}--${{ github.sha }} 50 | path: artefacts 51 | if-no-files-found: error 52 | -------------------------------------------------------------------------------- /lib/scenario-8/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": "nixpkgs-lib" 6 | }, 7 | "locked": { 8 | "lastModified": 1715865404, 9 | "narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=", 10 | "owner": "hercules-ci", 11 | "repo": "flake-parts", 12 | "rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "hercules-ci", 17 | "repo": "flake-parts", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1710889954, 24 | "narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixpkgs-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "nixpkgs-lib": { 38 | "locked": { 39 | "lastModified": 1715709767, 40 | "narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=", 41 | "type": "tarball", 42 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 43 | }, 44 | "original": { 45 | "type": "tarball", 46 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 47 | } 48 | }, 49 | "root": { 50 | "inputs": { 51 | "flake-parts": "flake-parts", 52 | "nixpkgs": "nixpkgs" 53 | } 54 | } 55 | }, 56 | "root": "root", 57 | "version": 7 58 | } 59 | -------------------------------------------------------------------------------- /lib/scenario-9/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": "nixpkgs-lib" 6 | }, 7 | "locked": { 8 | "lastModified": 1715865404, 9 | "narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=", 10 | "owner": "hercules-ci", 11 | "repo": "flake-parts", 12 | "rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "hercules-ci", 17 | "repo": "flake-parts", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1710889954, 24 | "narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixpkgs-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "nixpkgs-lib": { 38 | "locked": { 39 | "lastModified": 1715709767, 40 | "narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=", 41 | "type": "tarball", 42 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 43 | }, 44 | "original": { 45 | "type": "tarball", 46 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 47 | } 48 | }, 49 | "root": { 50 | "inputs": { 51 | "flake-parts": "flake-parts", 52 | "nixpkgs": "nixpkgs" 53 | } 54 | } 55 | }, 56 | "root": "root", 57 | "version": 7 58 | } 59 | -------------------------------------------------------------------------------- /resources/images/rules.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/thesis/theme/common/metadata.typ: -------------------------------------------------------------------------------- 1 | // Enter your thesis data here: 2 | #let title = "Reproducibility in Software Engineering" 3 | #let subtitle = "Community Edition" 4 | #let doi = "10.5281/zenodo.12666898" 5 | #let university = "University of Mons" 6 | #let faculty = "Faculty of Sciences" 7 | #let degree = "Master" 8 | #let program = "Computer Science" 9 | #let view = degree + "'s Thesis in " + program 10 | #let supervisor = [#link( 11 | "https://orcid.org/0000-0003-3636-5020", 12 | )[Prof. Dr. Tom Mens#box(image("../../../../resources/images/ORCIDiD_iconvector.svg", width: 10pt))]] 13 | #let advisors = none 14 | #let author = "Pol Dellaiera" 15 | #let authorOrcId = "0009-0008-7972-7160" 16 | #let startDate = "2023 - 2024" 17 | #let submissionDate = "12 June 2024" 18 | #let body-font = "New Computer Modern" 19 | #let sans-font = "New Computer Modern Sans" 20 | #let page-margin = (inside: 3cm, outside: 2cm, top: 20mm, bottom: 20mm) 21 | #let rev = if "rev" in sys.inputs { 22 | sys.inputs.rev 23 | } else { 24 | "" 25 | } 26 | #let shortRev = if "shortRev" in sys.inputs { 27 | sys.inputs.shortRev 28 | } else { 29 | "" 30 | } 31 | #let builddate = if "builddate" in sys.inputs { 32 | sys.inputs.builddate 33 | } else { 34 | "" 35 | } 36 | 37 | // Default font sizes from original LaTeX style file. 38 | #let font-defaults = ( 39 | tiny: 6pt, 40 | scriptsize: 7pt, 41 | footnotesize: 9pt, 42 | small: 9pt, 43 | normalsize: 10pt, 44 | large: 12pt, 45 | Large: 14pt, 46 | LARGE: 17pt, 47 | huge: 20pt, 48 | Huge: 25pt, 49 | ) 50 | 51 | #let font = ( 52 | Large: font-defaults.Large + 0.4pt, // Actual font size. 53 | footnote: font-defaults.footnotesize, 54 | large: font-defaults.large, 55 | small: font-defaults.small, 56 | normal: font-defaults.normalsize, 57 | script: font-defaults.scriptsize, 58 | raw: font-defaults.tiny, 59 | ) 60 | -------------------------------------------------------------------------------- /resources/sourcecode/nix-typst-build-diff.log: -------------------------------------------------------------------------------- 1 | --- /nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world 2 | +++ /nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world.check 3 | │ --- /nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world/hello-world.pdf 4 | ├── +++ /nix/store/1n4g9gsq34xzmg351r7sa87rrcazh8gf-typst-hello-world.check/hello-world.pdf 5 | │┄ 'pdftotext' not available in path. Falling back to binary comparison. 6 | │┄ Installing the 'pypdf' Python module may produce a better output. 7 | │ @@ -9457,17 +9457,17 @@ 8 | │ 00024f00: 6e65 730a 2020 2f46 6972 7374 2032 3820 nes. /First 28 9 | │ 00024f10: 3020 520a 2020 2f4c 6173 7420 3238 2030 0 R. /Last 28 0 10 | │ 00024f20: 2052 0a20 202f 436f 756e 7420 310a 3e3e R. /Count 1.>> 11 | │ 00024f30: 0a65 6e64 6f62 6a0a 0a32 3920 3020 6f62 .endobj..29 0 ob 12 | │ 00024f40: 6a0a 3c3c 0a20 202f 4372 6561 746f 7220 j.<<. /Creator 13 | │ 00024f50: 2854 7970 7374 2030 2e31 312e 3029 0a20 (Typst 0.11.0). 14 | │ 00024f60: 202f 4372 6561 7469 6f6e 4461 7465 2028 /CreationDate ( 15 | │ -00024f70: 443a 3230 3234 3033 3230 3137 3537 3132 D:20240320175712 16 | │ +00024f70: 443a 3230 3234 3033 3230 3138 3130 3535 D:20240320181055 17 | │ 00024f80: 5a29 0a20 202f 4d6f 6444 6174 6520 2844 Z). /ModDate (D 18 | │ -00024f90: 3a32 3032 3430 3332 3031 3735 3731 325a :20240320175712Z 19 | │ +00024f90: 3a32 3032 3430 3332 3031 3831 3035 355a :20240320181055Z 20 | │ 00024fa0: 290a 3e3e 0a65 6e64 6f62 6a0a 0a33 3020 ).>>.endobj..30 21 | │ 00024fb0: 3020 6f62 6a0a 3c3c 0a20 202f 4c65 6e67 0 obj.<<. /Leng 22 | │ 00024fc0: 7468 2039 3836 0a20 202f 5479 7065 202f th 986. /Type / 23 | │ 00024fd0: 4d65 7461 6461 7461 0a20 202f 5375 6274 Metadata. /Subt 24 | │ 00024fe0: 7970 6520 2f58 4d4c 0a3e 3e0a 7374 7265 ype /XML.>>.stre 25 | │ 00024ff0: 616d 0a3c 3f78 7061 636b 6574 2062 6567 am. 38 | -------------------------------------------------------------------------------- /lib/scenario-5/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": "nixpkgs-lib" 6 | }, 7 | "locked": { 8 | "lastModified": 1709336216, 9 | "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", 10 | "owner": "hercules-ci", 11 | "repo": "flake-parts", 12 | "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "id": "flake-parts", 17 | "type": "indirect" 18 | } 19 | }, 20 | "nixpkgs": { 21 | "locked": { 22 | "lastModified": 1710889954, 23 | "narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=", 24 | "owner": "NixOS", 25 | "repo": "nixpkgs", 26 | "rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b", 27 | "type": "github" 28 | }, 29 | "original": { 30 | "owner": "NixOS", 31 | "ref": "nixpkgs-unstable", 32 | "repo": "nixpkgs", 33 | "type": "github" 34 | } 35 | }, 36 | "nixpkgs-lib": { 37 | "locked": { 38 | "dir": "lib", 39 | "lastModified": 1709237383, 40 | "narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=", 41 | "owner": "NixOS", 42 | "repo": "nixpkgs", 43 | "rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8", 44 | "type": "github" 45 | }, 46 | "original": { 47 | "dir": "lib", 48 | "owner": "NixOS", 49 | "ref": "nixos-unstable", 50 | "repo": "nixpkgs", 51 | "type": "github" 52 | } 53 | }, 54 | "root": { 55 | "inputs": { 56 | "flake-parts": "flake-parts", 57 | "nixpkgs": "nixpkgs", 58 | "systems": "systems" 59 | } 60 | }, 61 | "systems": { 62 | "locked": { 63 | "lastModified": 1681028828, 64 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 65 | "owner": "nix-systems", 66 | "repo": "default", 67 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 68 | "type": "github" 69 | }, 70 | "original": { 71 | "owner": "nix-systems", 72 | "repo": "default", 73 | "type": "github" 74 | } 75 | } 76 | }, 77 | "root": "root", 78 | "version": 7 79 | } 80 | -------------------------------------------------------------------------------- /lib/scenario-6/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": "nixpkgs-lib" 6 | }, 7 | "locked": { 8 | "lastModified": 1709336216, 9 | "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", 10 | "owner": "hercules-ci", 11 | "repo": "flake-parts", 12 | "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "id": "flake-parts", 17 | "type": "indirect" 18 | } 19 | }, 20 | "nixpkgs": { 21 | "locked": { 22 | "lastModified": 1710889954, 23 | "narHash": "sha256-Pr6F5Pmd7JnNEMHHmspZ0qVqIBVxyZ13ik1pJtm2QXk=", 24 | "owner": "NixOS", 25 | "repo": "nixpkgs", 26 | "rev": "7872526e9c5332274ea5932a0c3270d6e4724f3b", 27 | "type": "github" 28 | }, 29 | "original": { 30 | "owner": "NixOS", 31 | "ref": "nixpkgs-unstable", 32 | "repo": "nixpkgs", 33 | "type": "github" 34 | } 35 | }, 36 | "nixpkgs-lib": { 37 | "locked": { 38 | "dir": "lib", 39 | "lastModified": 1709237383, 40 | "narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=", 41 | "owner": "NixOS", 42 | "repo": "nixpkgs", 43 | "rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8", 44 | "type": "github" 45 | }, 46 | "original": { 47 | "dir": "lib", 48 | "owner": "NixOS", 49 | "ref": "nixos-unstable", 50 | "repo": "nixpkgs", 51 | "type": "github" 52 | } 53 | }, 54 | "root": { 55 | "inputs": { 56 | "flake-parts": "flake-parts", 57 | "nixpkgs": "nixpkgs", 58 | "systems": "systems" 59 | } 60 | }, 61 | "systems": { 62 | "locked": { 63 | "lastModified": 1681028828, 64 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 65 | "owner": "nix-systems", 66 | "repo": "default", 67 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 68 | "type": "github" 69 | }, 70 | "original": { 71 | "owner": "nix-systems", 72 | "repo": "default", 73 | "type": "github" 74 | } 75 | } 76 | }, 77 | "root": "root", 78 | "version": 7 79 | } 80 | -------------------------------------------------------------------------------- /resources/images/inputs-cube.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/thesis/imports/workarounds.typ: -------------------------------------------------------------------------------- 1 | #import "@preview/codly:1.3.0": * 2 | #import "@preview/codly-languages:0.1.8": * 3 | #import "../theme/common/metadata.typ": * 4 | 5 | #let sourcefile(file: none, lang: none) = { 6 | set par(justify: false) 7 | set align(left) 8 | 9 | show: codly-init.with() 10 | 11 | // --- Raw text configuration --- 12 | show raw: set text(size: font.raw) 13 | 14 | codly( 15 | languages: codly-languages, 16 | number-format: number => { 17 | text(fill: luma(75%), [#number]) 18 | }, 19 | zebra-fill: none, 20 | stroke: .6pt + luma(200), 21 | fill: luma(250), 22 | inset: .25em, 23 | radius: 3pt, 24 | lang-outset: (x: 0pt, y: 2pt), 25 | skip-last-empty: true, 26 | ) 27 | 28 | raw(read(file), lang: lang, block: true) 29 | } 30 | 31 | #let shell(file: none) = { 32 | // --- Raw text configuration --- 33 | show raw: set text(size: font.raw) 34 | 35 | let body = [#read(file)] 36 | 37 | let kinds = ( 38 | "$": green.darken(30%), 39 | "#": blue.darken(10%), 40 | ">": luma(40%), 41 | " ": luma(100%), 42 | ) 43 | 44 | let lines = body 45 | .text 46 | .split("\n") 47 | .map(line => { 48 | if line.at(0, default: "") in kinds and line.at(1, default: "") == " " { 49 | (line.at(0), line.slice(2)) 50 | } else { 51 | (none, line) 52 | } 53 | }) 54 | 55 | show raw.line: it => [ 56 | #let (kind, line) = lines.at(it.number - 1) 57 | #if kind != none { 58 | text(fill: kinds.at(kind), kind) + " " + line 59 | } else { 60 | text(fill: luma(50%), it.text) 61 | } 62 | ] 63 | 64 | show: codly-init.with() 65 | 66 | codly( 67 | languages: codly-languages, 68 | number-format: number => { 69 | text(fill: luma(75%), [#number]) 70 | }, 71 | zebra-fill: none, 72 | stroke: .6pt + luma(200), 73 | fill: luma(250), 74 | inset: .4em, 75 | radius: 3pt, 76 | lang-outset: (x: 0pt, y: 0pt), 77 | skip-last-empty: true, 78 | ) 79 | 80 | raw(read(file), lang: "shell", block: true) 81 | } 82 | 83 | #let LaTeX = { 84 | [L] 85 | box(move(dx: -4.2pt, dy: -1.2pt, box(scale(65%)[A]))) 86 | box(move(dx: -5.7pt, dy: 0pt, [T])) 87 | box(move(dx: -7.0pt, dy: 2.7pt, box(scale(100%)[E]))) 88 | box(move(dx: -8.0pt, dy: 0pt, [X])) 89 | h(-8.0pt) 90 | } 91 | 92 | #let eg = content => { 93 | [(e.g., #content)] 94 | } 95 | 96 | #show "LaTeX": LaTeX 97 | -------------------------------------------------------------------------------- /src/thesis/acknowledgement.typ: -------------------------------------------------------------------------------- 1 | #import "theme/acknowledgement.typ": * 2 | 3 | #acknowledgement[ 4 | First and foremost, I would like to express my deepest gratitude to Professor 5 | Tom Mens. I am incredibly thankful for his availability and guidance 6 | throughout my studies. It was a great honour to receive his proposal to 7 | supervise my research in my final year. Beyond that, he generously 8 | allowed me to suggest topics that piqued my interest, ultimately enabling me 9 | to focus on a subject that I am truly passionate about. 10 | 11 | I must also express my heartfelt appreciation for my girlfriend, Sandra. Her 12 | endless patience and emotional support have been a constant source of 13 | strength, motivation and inspiration for me. However, it is with a touch of 14 | melancholy that I acknowledge the sacrifices we have made in our personal 15 | lives in order to pursue this overdue academic endeavour that I should have 16 | completed twenty years ago. 17 | 18 | I would like to thank my family and #emph[in-real-life] friends for their 19 | continuous support and encouragement throughout these last years. Your belief 20 | in me has provided the foundation upon which this work stands. I am also 21 | deeply grateful to my #emph[online] friends, especially within the Typst and 22 | Nix communities, for their tremendous support and constant source of 23 | solutions, inspiration and motivation. 24 | 25 | A special mention is deserved for Izumi, my cat, who was a constant companion 26 | and source of comfort over the last decade. His loss was a profound sorrow, 27 | and I deeply miss his presence. The memories of the countless hours he spent 28 | by my side, offering silent support during my work, have left an indelible 29 | mark. 30 | 31 | Finally, I would like to express my sincere thanks to all the participants in 32 | this research. I am particularly grateful to my colleagues at European 33 | Commission, who courageously and continuously supported me while remaining 34 | unaware of my academic activities. Your valuable feedback has greatly 35 | contributed to the development of some parts of this master's thesis. In fact, 36 | your lack of awareness helped me understand the barriers to implementing 37 | software reproducibility from the very beginning and in a real professional 38 | context. Each piece of feedback has been instrumental in helping me better 39 | understand and improve communication about this concept. 40 | ] 41 | -------------------------------------------------------------------------------- /resources/typst/essawy.typ: -------------------------------------------------------------------------------- 1 | #{ 2 | set text( 3 | font: "Virgil", 4 | size: .9em, 5 | ) 6 | box[ 7 | #grid( 8 | columns: 1, 9 | rows: 4, 10 | gutter: 0pt, 11 | polygon( 12 | fill: blue.lighten(80%), 13 | stroke: blue, 14 | (0pt, 3.5cm), 15 | (70pt, 0cm), 16 | (140pt, 3.5cm), 17 | ), 18 | polygon( 19 | fill: blue.lighten(80%), 20 | stroke: blue, 21 | (0pt, 2cm), 22 | (40pt, 0pt), 23 | (180pt, 0pt), 24 | (220pt, 2cm), 25 | ), 26 | polygon( 27 | fill: blue.lighten(80%), 28 | stroke: blue, 29 | (0pt, 2cm), 30 | (40pt, 0pt), 31 | (260pt, 0pt), 32 | (300pt, 2cm), 33 | ), 34 | polygon( 35 | fill: blue.lighten(80%), 36 | stroke: blue, 37 | (0pt, 2cm), 38 | (40pt, 0pt), 39 | (340pt, 0pt), 40 | (380pt, 2cm), 41 | ), 42 | ) 43 | 44 | // Right line 45 | #place(bottom + left)[ 46 | #line(length: 320pt, angle: 55deg, start: (216pt, 0pt)) 47 | ] 48 | 49 | // Left line 50 | #place(bottom + right)[ 51 | #line(length: 320pt, angle: -55deg, start: (-400pt, 0pt)) 52 | ] 53 | 54 | // Left arrow 55 | #place(top + left, dx: 161pt)[ 56 | #rotate(35deg)[ 57 | #polygon.regular(fill: black, size: 10pt, vertices: 3) 58 | ] 59 | ] 60 | 61 | // Text left 62 | #place(bottom + left, dx: 50pt, dy: -125pt)[ 63 | #rotate(-55deg)[ 64 | time 65 | ] 66 | ] 67 | 68 | // Right arrow 69 | #place(top + right, dx: -161pt)[ 70 | #rotate(-35deg)[ 71 | #polygon.regular(fill: black, size: 10pt, vertices: 3) 72 | ] 73 | ] 74 | 75 | // Text right 76 | #place(bottom + left, dx: 300pt, dy: -130pt)[ 77 | #rotate(55deg)[ 78 | effort 79 | ] 80 | ] 81 | 82 | #place(center, dy: -45pt)[ 83 | Repeatability\ 84 | 85 | Original researcher,\ machine and data 86 | ] 87 | 88 | #place(center, dy: -105pt)[ 89 | Runnability\ 90 | 91 | Original researcher and data\ other machine 92 | ] 93 | 94 | #place(center, dy: -160pt)[ 95 | Reproducibility\ 96 | 97 | Original data\ other researcher and machine 98 | ] 99 | 100 | #place(center, dy: -215pt)[ 101 | Replicability\ 102 | 103 | Other researcher,\ 104 | machine and data 105 | ] 106 | ] 107 | } 108 | -------------------------------------------------------------------------------- /.github/workflows/build-main.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "src/**" 9 | - "resources/**" 10 | - "**.nix" 11 | - ".github/workflows/*.yml" 12 | 13 | jobs: 14 | dependencies: 15 | name: Build dependencies 16 | runs-on: ubuntu-latest 17 | outputs: 18 | branch: ${{ steps.extract_branch.outputs.branch }} 19 | 20 | steps: 21 | - name: Check out source files 22 | uses: actions/checkout@v4 23 | 24 | - name: Extract branch name 25 | shell: bash 26 | run: 27 | echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> 28 | $GITHUB_OUTPUT 29 | id: extract_branch 30 | 31 | build: 32 | name: Build PDF files 33 | runs-on: ubuntu-latest 34 | needs: [dependencies] 35 | 36 | steps: 37 | - name: Set git to use LF 38 | run: | 39 | git config --global core.autocrlf false 40 | git config --global core.eol lf 41 | 42 | - name: Check out source files 43 | uses: actions/checkout@v4 44 | 45 | - name: Install Nix 46 | uses: cachix/install-nix-action@v31 47 | 48 | - name: Build document 49 | run: | 50 | mkdir -p output 51 | nix build .#thesis --out-link result-thesis --quiet 52 | cp -vr --dereference $(readlink -f result-thesis) thesis 53 | cp -ar thesis/* output/ 54 | 55 | - name: Upload build assets 56 | uses: actions/upload-artifact@v5 57 | with: 58 | name: artefacts 59 | path: output 60 | 61 | assets: 62 | name: Create release 63 | runs-on: ubuntu-latest 64 | needs: [dependencies, build] 65 | 66 | steps: 67 | - name: Download build assets (${{ matrix.assets.input }}) 68 | uses: actions/download-artifact@v6 69 | 70 | - name: Rename files 71 | working-directory: artefacts 72 | run: | 73 | for f in *.pdf; do cp ${f} ../$(printf '%s\n' "${{ github.run_number }}--${f%.pdf}--${{ github.sha }}.pdf"); done 74 | 75 | - name: 76 | Create pre-release (v${{ github.run_number }}-${{ github.sha 77 | }}) 78 | id: create_release 79 | uses: softprops/action-gh-release@v2 80 | env: 81 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 82 | with: 83 | tag_name: v${{ github.run_number }}-${{ github.sha }} 84 | name: Release ${{ github.run_number }} (${{ github.sha }}) 85 | draft: false 86 | prerelease: true 87 | files: | 88 | ./*.pdf 89 | -------------------------------------------------------------------------------- /src/thesis/theme/common/titlepage.typ: -------------------------------------------------------------------------------- 1 | #import "metadata.typ": * 2 | 3 | #let titlepage( 4 | title: "", 5 | subtitle: "", 6 | university: "", 7 | faculty: "", 8 | degree: "", 9 | program: "", 10 | supervisor: "", 11 | advisors: (), 12 | author: "", 13 | authorOrcId: "", 14 | doi: none, 15 | startDate: none, 16 | submissionDate: none, 17 | rev: none, 18 | shortRev: none, 19 | builddate: none, 20 | ) = { 21 | set page( 22 | margin: (top: 1cm, left: 1cm, right: 1cm, bottom: 1cm), 23 | numbering: none, 24 | number-align: center, 25 | header: { 26 | place(top + left)[ 27 | #pad(top: 10pt)[ 28 | #set text(size: 4em) 29 | #include "../UMONS-fs-logo.typ" 30 | ] 31 | ] 32 | place(top + right)[ 33 | #pad(top: 10pt)[ 34 | #set text(size: 4em) 35 | #include "../UMONS-logo.typ" 36 | ] 37 | ] 38 | }, 39 | footer: align(center, text(font: sans-font)[ 40 | #faculty #sym.diamond.filled.small 41 | #university #sym.diamond.filled.small 42 | 20, Place du Parc #sym.diamond.filled.small 43 | B-7000 Mons 44 | ]), 45 | ) 46 | 47 | set text( 48 | font: body-font, 49 | size: 12pt, 50 | lang: "en", 51 | ) 52 | 53 | place(center + horizon, dy: 3em)[ 54 | #align(center, text(font: sans-font, 2em, weight: 700, title)) 55 | 56 | #if subtitle != none { 57 | align(center, text(font: sans-font, 1em, weight: 700, subtitle)) 58 | } 59 | 60 | #align(center, text(font: sans-font, 1.3em, weight: 100, view)) 61 | 62 | #grid( 63 | columns: 3, 64 | gutter: 1em, 65 | align: (right, left, left), 66 | strong("Author"), 67 | ":", 68 | { 69 | link("https://orcid.org/" + authorOrcId)[#author#box(image( 70 | "../../../../resources/images/ORCIDiD_iconvector.svg", 71 | width: 10pt, 72 | ))] 73 | }, 74 | strong("Supervisor"), 75 | ":", 76 | supervisor, 77 | ..if advisors != none { 78 | (strong("Advisors"), ":", advisors.join(", ")) 79 | }, 80 | ..if startDate != none { 81 | (strong("Academic year"), ":", startDate) 82 | }, 83 | ..if submissionDate != none { 84 | (strong("Submission date"), ":", submissionDate) 85 | }, 86 | ..if builddate != "" { 87 | (strong("Build date"), ":", builddate) 88 | }, 89 | ..if doi != none { 90 | ( 91 | strong("DOI"), 92 | ":", 93 | link( 94 | "https://doi.org/" + doi, 95 | doi, 96 | ), 97 | ) 98 | }, 99 | ..if shortRev != "" { 100 | ( 101 | strong("Revision"), 102 | ":", 103 | link( 104 | "https://codeberg.org/p1ld7a/master-thesis/commit/" + rev, 105 | shortRev, 106 | ), 107 | ) 108 | }, 109 | ) 110 | ] 111 | } 112 | -------------------------------------------------------------------------------- /src/thesis/accessibility.typ: -------------------------------------------------------------------------------- 1 | #import "imports/preamble.typ": * 2 | 3 | #pagebreak(weak: true) 4 | 5 | #heading("Accessibility", level: 1, outlined: false) 6 | 7 | This master thesis has been written with a focus on accessibility to ensure it 8 | can be easily read and understood by a diverse audience, including individuals 9 | with disabilities. The following measures have been taken to enhance 10 | accessibility: 11 | 12 | - Links: all hyperlinks within this document are underlined and clearly 13 | distinguishable from regular text. This visual cue helps users identify 14 | clickable links easily. 15 | 16 | - Symbols and notation: specific symbols and notation have been used 17 | consistently throughout the document to aid comprehension. Mathematical 18 | symbols, special characters, and other notation are presented in a clear and 19 | readable manner. 20 | 21 | - Text formatting: the document uses high-contrast text formatting and font 22 | sizes that are readable across different devices and screen resolutions. The 23 | `New Computer Modern` #cite(, form: "normal") font is used, 24 | chosen for its clarity and readability, especially in mathematical and 25 | technical contexts. 26 | 27 | - Margins: the margins have been alternately adapted to ensure that when the 28 | document is printed, it is suitable for binding and easy to read. This 29 | consideration enhances the physical accessibility of the printed document. 30 | 31 | - Headings and structure: the document is structured with clear headings and 32 | subheadings to facilitate navigation. This hierarchical organisation assists 33 | readers in quickly finding relevant sections. 34 | 35 | - Language and terminology: plain language and concise terminology have been 36 | employed to ensure that the content is comprehensible to a broad audience, 37 | including those for whom English is not their first language. 38 | 39 | - Glossary: a #link()[glossary] is included, containing the 40 | most common abbreviations used throughout the document. This aids readers in 41 | quickly understanding the abbreviations and acronyms, improving overall 42 | comprehension. Additionally, comprehensive lists of 43 | #link()[definitions], #link()[figures], 44 | and #link()[tables] are provided. 45 | 46 | - Accessible file formats: the document is available in multiple file formats, 47 | to accommodate various reading preferences and assistive technologies. 48 | 49 | - Bibliography links: in line with the #gls("IEEE") citation style, numbers in 50 | brackets are used to link references in the 51 | #link()[bibliography]. This method provides a clear and 52 | consistent way to reference sources, enhancing the readability and 53 | accessibility of the document. 54 | 55 | - Images: all images in this document are in #gls("SVG") format. This vectorial 56 | format ensures that images are scalable without loss of quality, providing 57 | clear and accessible visuals on different devices and screen resolutions. 58 | -------------------------------------------------------------------------------- /nix/imports/typst.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ inputs.make-shell.flakeModules.default ]; 4 | 5 | perSystem = 6 | { 7 | pkgs, 8 | lib, 9 | ... 10 | }: 11 | let 12 | typst = pkgs.typst.withPackages (p: [ 13 | p.diagraph 14 | p.codly 15 | p.codly-languages 16 | p.glossarium 17 | p.xarrow 18 | p.hydra 19 | p.cetz 20 | p.cetz-plot 21 | ]); 22 | 23 | typst-fonts = pkgs.symlinkJoin { 24 | name = "typst-fonts"; 25 | paths = with pkgs; [ 26 | inriafonts 27 | fg-virgil 28 | liberation_ttf 29 | nerd-fonts.inconsolata 30 | newcomputermodern 31 | ]; 32 | }; 33 | 34 | mkTypstScript = 35 | action: documentName: 36 | pkgs.writeShellApplication { 37 | name = "typst-${action}-${documentName}"; 38 | 39 | runtimeInputs = [ typst ]; 40 | 41 | text = '' 42 | ${lib.getExe typst} \ 43 | ${action} \ 44 | --root ./. \ 45 | --input rev="${inputs.self.rev or ""}" \ 46 | --input shortRev="${inputs.self.shortRev or ""}" \ 47 | --input builddate="$(date -u -d @${toString (inputs.self.lastModified or "")})" \ 48 | --font-path ${typst-fonts} \ 49 | --ignore-system-fonts \ 50 | ./src/${documentName}/main.typ \ 51 | ${documentName}.pdf 52 | ''; 53 | }; 54 | 55 | mkBuildDocumentDrv = 56 | action: documentName: 57 | pkgs.stdenvNoCC.mkDerivation { 58 | pname = "typst-${action}-${documentName}"; 59 | version = "0.0.1"; 60 | 61 | src = pkgs.lib.cleanSource ./../../.; 62 | 63 | buildInputs = [ typst ]; 64 | 65 | buildPhase = '' 66 | runHook preBuild 67 | 68 | ${lib.getExe (mkTypstScript "compile" documentName)} 69 | 70 | runHook postBuild 71 | ''; 72 | 73 | installPhase = '' 74 | runHook preInstall 75 | 76 | install -m640 -D ${documentName}.* -t $out 77 | 78 | runHook postInstall 79 | ''; 80 | }; 81 | 82 | documentDrvs = lib.genAttrs (lib.attrNames ( 83 | lib.filterAttrs (_k: v: (v == "directory")) (builtins.readDir ../../src) 84 | )) (d: (mkBuildDocumentDrv "compile" d)); 85 | 86 | scriptDrvs = lib.foldl' ( 87 | a: i: 88 | a 89 | // { 90 | "compile-${i}" = (mkTypstScript "compile" i); 91 | "watch-${i}" = (mkTypstScript "watch" i); 92 | } 93 | ) { } (lib.attrNames documentDrvs); 94 | in 95 | { 96 | packages = documentDrvs; 97 | 98 | make-shells.default = { 99 | packages = [ typst ] ++ lib.attrValues scriptDrvs; 100 | env = { 101 | TYPST_FONT_PATHS = "${typst-fonts}/share/fonts"; 102 | TYPST_PACKAGE_PATH = "${typst}/lib/typst/packages"; 103 | }; 104 | }; 105 | 106 | checks = documentDrvs; 107 | }; 108 | } 109 | -------------------------------------------------------------------------------- /resources/typst/ch4-table-conclusion.typ: -------------------------------------------------------------------------------- 1 | #set align(left) 2 | 3 | #table( 4 | columns: (1fr, 1fr), 5 | stroke: none, 6 | [#align(center)[Pros]], 7 | table.vline(stroke: .5pt), 8 | [#align(center)[Cons]], 9 | table.hline(stroke: .5pt), 10 | [ 11 | Facilitates collaboration and onboarding: 12 | 13 | Reproducibility enables easier collaboration among researchers, developers, 14 | as they can replicate and extend each other's work more efficiently. 15 | ], 16 | [ 17 | Steep learning curve: 18 | 19 | Implementing reproducibility practices may require learning new tools and 20 | methodologies, which can be time-consuming and challenging. 21 | ], 22 | table.hline(stroke: .5pt), 23 | [ 24 | Transparency and trust: 25 | 26 | By sharing the methods, data, and tools used in research and development, 27 | other collaborators can verify and build upon the work, fostering a culture 28 | of openness and collaboration. 29 | ], 30 | [ 31 | Complexity: 32 | 33 | The process of making software reproducible can be complex, especially if it 34 | has not been setup from the beginning of the project. 35 | ], 36 | table.hline(stroke: .5pt), 37 | [ 38 | Improves software quality: 39 | 40 | Reproducibility practices help in identifying and fixing bugs, improving the 41 | software's overall quality and robustness. 42 | ], 43 | [ 44 | Proliferation of package managers: 45 | 46 | The existence of too many package managers that 47 | are built without reproducibility in mind can add another layer of complexity when trying to build software reproducibly. 48 | ], 49 | table.hline(stroke: .5pt), 50 | [ 51 | Enhanced reliability and validity: 52 | 53 | Reproducible results provide confidence that findings are accurate and not 54 | due to random chance or specific initial conditions of a single experiment. 55 | ], 56 | [ 57 | Factors limiting reproducibility: 58 | 59 | Factors such as proprietary software, licensing issues, and evolving 60 | hardware can pose challenges to achieving full reproducibility. 61 | ], 62 | table.hline(stroke: .5pt), 63 | [ 64 | Security and integrity: 65 | 66 | Ensuring that software can be reliably rebuilt from its source helps in 67 | detecting unauthorized changes, enhancing security, and maintaining the 68 | integrity of the software supply chain. 69 | ], 70 | [ 71 | Potential for misuse: 72 | 73 | Over-reliance on automated reproducibility tools can lead to complacency, 74 | where developers might not fully understand the underlying processes and 75 | methodologies. 76 | ], 77 | table.hline(stroke: .5pt), 78 | [ 79 | Facilitates troubleshooting and debugging: 80 | 81 | Reproducible experiments serve as a clear benchmark for comparison, 82 | assisting teams in identifying discrepancies, tracing error origins, and 83 | incrementally enhancing model performance​. 84 | ], 85 | [ 86 | Potential for stagnation: 87 | 88 | Emphasis on reproducibility might slow down innovation as developers might 89 | spend more time ensuring reproducibility rather than exploring new ideas and 90 | methodologies​. 91 | ], 92 | ) 93 | -------------------------------------------------------------------------------- /src/thesis/theme/infos.typ: -------------------------------------------------------------------------------- 1 | #import "./colors.typ": * 2 | 3 | #let info-settings = ( 4 | info: ( 5 | prefix: none, 6 | icon: "circle-info", 7 | fill_color: umons-turquoise.lighten(90%), 8 | stroke_color: umons-turquoise, 9 | ), 10 | cite: ( 11 | prefix: none, 12 | icon: "quote-left", 13 | fill_color: rgb("#ffffff"), 14 | stroke_color: black, 15 | ), 16 | definition: ( 17 | prefix: [#underline(smallcaps[*Definition*])], 18 | icon: "highlighter-solid", 19 | fill_color: umons-faculty-sciences.lighten(90%), 20 | stroke_color: umons-faculty-sciences, 21 | ), 22 | question: ( 23 | prefix: none, 24 | icon: "circle-question", 25 | fill_color: umons-yellow.lighten(90%), 26 | stroke_color: umons-yellow, 27 | ), 28 | important: ( 29 | prefix: none, 30 | icon: "circle-exclamation", 31 | fill_color: rgb("#228B22").lighten(90%), 32 | stroke_color: rgb("#228B22").darken(20%), 33 | ), 34 | conclusion: ( 35 | prefix: none, 36 | icon: "lightbulb-solid", 37 | fill_color: umons-red.lighten(90%), 38 | stroke_color: umons-red, 39 | ), 40 | good: ( 41 | prefix: none, 42 | icon: "circle-check", 43 | fill_color: umons-grey.lighten(90%), 44 | stroke_color: umons-grey.darken(20%), 45 | ), 46 | note: ( 47 | prefix: [ *Note:* ], 48 | icon: "note-sticky", 49 | fill_color: umons-grey.lighten(90%), 50 | stroke_color: umons-grey.darken(20%), 51 | ), 52 | ); 53 | 54 | #let info-stroke(kind: "good") = info-settings.at(kind).stroke_color 55 | 56 | #let info-image(kind: "info", ..args) = { 57 | let settings = info-settings.at(kind) 58 | image("solid/" + settings.icon + ".svg", ..args, alt: settings.icon) 59 | } 60 | 61 | #let info-box( 62 | body, 63 | settings: (:), 64 | kind: "info", 65 | radius: 5pt, 66 | footer: none, 67 | icon: true, 68 | ref: none, 69 | ) = { 70 | set par( 71 | leading: 0.55em, 72 | justify: true, 73 | ) 74 | 75 | let settings = info-settings.at(kind) + settings 76 | let extra = if footer == none { 77 | none 78 | } else { 79 | v(.5em) 80 | h(1fr) 81 | text(size: .75em)[#footer] 82 | } 83 | 84 | set align(left) 85 | 86 | box( 87 | width: 0.8fr, 88 | fill: settings.fill_color, 89 | stroke: .5pt + settings.stroke_color, 90 | radius: radius, 91 | inset: 0pt, 92 | )[ 93 | #let body = if kind == "cite" { 94 | quote(attribution: extra, quotes: false)[#emph(body)] 95 | } else { 96 | body 97 | } 98 | 99 | #let contents = if icon { 100 | ( 101 | image( 102 | "../../../resources/images/" + settings.icon + ".svg", 103 | width: 32pt, 104 | ), 105 | ( 106 | { 107 | settings.prefix 108 | body 109 | extra 110 | } 111 | ), 112 | ) 113 | } else { 114 | ( 115 | { 116 | settings.prefix 117 | body 118 | extra 119 | } 120 | ) 121 | } 122 | #figure(kind: "info-box", supplement: [Info box], { 123 | set align(left) 124 | table( 125 | columns: if icon { 126 | (38pt, 1fr) 127 | } else { 128 | 1 129 | }, 130 | inset: 10pt, 131 | stroke: none, 132 | column-gutter: 10pt, 133 | ..contents, 134 | ) 135 | }) #{ 136 | if ref != none { 137 | label(ref) 138 | } else { 139 | none 140 | } 141 | } 142 | ] 143 | } 144 | -------------------------------------------------------------------------------- /resources/typst/ch3-table-conclusion.typ: -------------------------------------------------------------------------------- 1 | #set text( 2 | size: .80em, 3 | hyphenate: true, 4 | ) 5 | #set par(justify: true) 6 | #set text() 7 | 8 | #table( 9 | columns: 6, 10 | stroke: none, 11 | align: (right,) + (left,) * 2 + (center,) * 4, 12 | table.header( 13 | table.cell(rowspan: 2, align: horizon + center)[], 14 | table.vline(stroke: .5pt), 15 | table.cell(rowspan: 2, align: horizon + center)[Pro], 16 | table.vline(stroke: .5pt), 17 | table.cell(rowspan: 2, align: horizon + center)[Cons], 18 | table.vline(stroke: .5pt), 19 | table.cell( 20 | colspan: 3, 21 | )[Reproducible\ within the same\ hardware architecture], 22 | [In space], 23 | table.vline(stroke: .5pt + black.lighten(75%)), 24 | [In time], 25 | table.vline(stroke: .5pt + black.lighten(75%)), 26 | [Environment], 27 | table.hline(stroke: .5pt), 28 | ), 29 | table.cell(align: horizon + left)[1. #link()[Bare\ compilation]], 30 | [ 31 | - Full control over compilation 32 | - Direct understanding of dependencies inherited from host system 33 | ], 34 | [ 35 | - Prone to #emph["it works on my machine"] issues 36 | - Lacks isolation and dependency management 37 | ], 38 | table.cell(align: horizon + center, text(size: 2em)[\u{00D7}]), 39 | table.cell(align: horizon + center, text(size: 2em)[\u{00D7}]), 40 | table.cell(align: horizon + center, text(size: 2em)[\u{00D7}]), 41 | table.hline(stroke: .5pt + black.lighten(75%)), 42 | table.cell(align: horizon + left)[2. #link()[Docker]], 43 | [ 44 | - Better isolation and dependency management thanks to containerization 45 | - Isolation from host system 46 | - Popular solution, widely adopted 47 | ], 48 | [ 49 | - Potential variability due to base images and package management 50 | - Additional layer of abstraction due to containerization 51 | ], 52 | table.cell(align: horizon + center, text(size: 2em)[\u{223C}]), 53 | table.cell(align: horizon + center, text(size: 2em)[\u{223C}]), 54 | table.cell(align: horizon + center, text(size: 2em)[\u{223C}]), 55 | table.hline(stroke: .5pt + black.lighten(75%)), 56 | table.cell(align: horizon + left)[3. #link()[Guix]], 57 | table.cell(align: left + horizon)[ 58 | - Deterministic builds with explicit dependency specification 59 | - Functional package management 60 | - Immutable software environments 61 | - Isolation and environment reproducibility 62 | - No containerization overhead 63 | - Prone to long-term reproducibility 64 | ], 65 | [ 66 | - Steep learning curve 67 | - Paradigm shift from traditional package management systems required 68 | - Limited repository of packages 69 | ], 70 | table.cell(align: horizon + center, rowspan: 2, text(size: 2em)[\u{2713}]), 71 | table.cell(align: horizon + center, rowspan: 2, text(size: 2em)[\u{2713}]), 72 | table.cell(align: horizon + center, rowspan: 2, text(size: 2em)[\u{2713}]), 73 | table.hline(stroke: .5pt + black.lighten(75%)), 74 | table.cell(align: horizon + left)[4. #link()[Nix]], 75 | table.cell(align: left + horizon)[ 76 | - Deterministic builds with explicit dependency specification 77 | - Functional package management 78 | - Immutable software environments 79 | - Isolation and environment reproducibility 80 | - No containerization overhead 81 | - Vast repository of packages 82 | ], 83 | [ 84 | - Steep learning curve 85 | - Paradigm shift from traditional package management systems required 86 | ], 87 | table.footer( 88 | table.cell( 89 | align: right, 90 | colspan: 6, 91 | text(size: .7em)[ 92 | Legend: \u{2713} = Supported, \u{223C} = Partially supported, \u{00D7} = Not supported 93 | ], 94 | ), 95 | ), 96 | ) 97 | -------------------------------------------------------------------------------- /src/thesis/theme/UMONS-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 18 | 37 | 42 | UMONS 57 | University of Mons 68 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /.github/workflows/comment-pr.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Comment Artifact URL on PR 3 | 4 | on: 5 | workflow_run: 6 | types: 7 | - "completed" 8 | workflows: 9 | - "Build PR" 10 | 11 | jobs: 12 | comment: 13 | if: github.event.workflow_run.conclusion == 'success' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Get Artifact and Pull request info 17 | env: 18 | GITHUB_TOKEN: ${{ github.token }} 19 | WORKFLOW_RUN_EVENT_OBJ: 20 | ${{ toJSON(github.event.workflow_run) }} 21 | OWNER: ${{ github.repository_owner }} 22 | REPO: ${{ github.event.repository.name }} 23 | run: | 24 | PREVIOUS_JOB_ID=$(jq -r '.id' <<< "$WORKFLOW_RUN_EVENT_OBJ") 25 | echo "Previous Job ID: $PREVIOUS_JOB_ID" 26 | echo "PREVIOUS_JOB_ID=$PREVIOUS_JOB_ID" >> "$GITHUB_ENV" 27 | 28 | SUITE_ID=$(jq -r '.check_suite_id' <<< "$WORKFLOW_RUN_EVENT_OBJ") 29 | echo "Previous Suite ID: $SUITE_ID" 30 | echo "SUITE_ID=$SUITE_ID" >> "$GITHUB_ENV" 31 | 32 | ARTIFACT_ID=$(gh api "/repos/$OWNER/$REPO/actions/artifacts" \ 33 | --jq ".artifacts.[] | 34 | select(.workflow_run.id==${PREVIOUS_JOB_ID}) | 35 | select(.expired==false) | 36 | .id") 37 | 38 | echo "Artifact ID: $ARTIFACT_ID" 39 | echo "ARTIFACT_ID=$ARTIFACT_ID" >> "$GITHUB_ENV" 40 | 41 | PR_NUMBER=$(jq -r '.pull_requests[0].number' \ 42 | <<< "$WORKFLOW_RUN_EVENT_OBJ") 43 | 44 | echo "Pull request Number: $PR_NUMBER" 45 | echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_ENV" 46 | 47 | HEAD_SHA=$(jq -r '.pull_requests[0].head.sha' \ 48 | <<< "$WORKFLOW_RUN_EVENT_OBJ") 49 | 50 | echo "Head SHA: $HEAD_SHA" 51 | echo "HEAD_SHA=$HEAD_SHA" >> "$GITHUB_ENV" 52 | - name: Find Comment 53 | uses: peter-evans/find-comment@v4 54 | id: find-comment 55 | with: 56 | issue-number: ${{ env.PR_NUMBER }} 57 | comment-author: "github-actions[bot]" 58 | - name: Update Comment 59 | env: 60 | JOB_PATH: 61 | "${{ github.server_url }}/${{ github.repository 62 | }}/actions/runs/${{ env.PREVIOUS_JOB_ID }}" 63 | ARTIFACT_URL: 64 | "${{ github.server_url }}/${{ github.repository 65 | }}/suites/${{ env.SUITE_ID }}/artifacts/${{ 66 | env.ARTIFACT_ID }}" 67 | HEAD_SHA: "${{ env.HEAD_SHA }}" 68 | uses: peter-evans/create-or-update-comment@v5 69 | with: 70 | issue-number: ${{ env.PR_NUMBER }} 71 | comment-id: ${{ steps.find-comment.outputs.comment-id }} 72 | edit-mode: replace 73 | body: |- 74 | ![badge] 75 | 76 | Build Successful! You can find a link to the downloadable artifact below. 77 | 78 | | Name | Link | 79 | | -------- | ----------------------- | 80 | | Commit | ${{ env.HEAD_SHA }} | 81 | | Logs | ${{ env.JOB_PATH }} | 82 | | Download | ${{ env.ARTIFACT_URL }} | 83 | 84 | [badge]: https://img.shields.io/badge/Build_Success!-0d1117?style=for-the-badge&labelColor=3fb950&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSIjZmZmZmZmIj48cGF0aCBkPSJNMjEuMDMgNS43MmEuNzUuNzUgMCAwIDEgMCAxLjA2bC0xMS41IDExLjVhLjc0Ny43NDcgMCAwIDEtMS4wNzItLjAxMmwtNS41LTUuNzVhLjc1Ljc1IDAgMSAxIDEuMDg0LTEuMDM2bDQuOTcgNS4xOTVMMTkuOTcgNS43MmEuNzUuNzUgMCAwIDEgMS4wNiAwWiI+PC9wYXRoPjwvc3ZnPg== 85 | -------------------------------------------------------------------------------- /src/thesis/theme/UMONS_FS-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 34 | 36 | 42 | 44 | 47 | 48 | 50 | 53 | 54 | 55 | 58 | 60 | 64 | 68 | 72 | 76 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /resources/typst/configuration-management.typ: -------------------------------------------------------------------------------- 1 | #import "../../src/thesis/imports/preamble.typ": * 2 | 3 | #grid( 4 | columns: (1fr, 1fr, 1fr), 5 | gutter: 1em, 6 | [ 7 | #set align(bottom) 8 | #figure( 9 | { 10 | set text(font: "Virgil") 11 | cetz.canvas({ 12 | cetz.draw.set-style(axes: (shared-zero: false)) 13 | 14 | plot.plot( 15 | size: (3, 3), 16 | axis-style: "school-book", 17 | y-label: [State], 18 | x-label: [Time], 19 | x-tick-step: none, 20 | y-tick-step: none, 21 | x-min: 0, 22 | x-max: 500, 23 | x-grid: true, 24 | y-min: 0, 25 | y-max: 500, 26 | { 27 | plot.add( 28 | ((75, 75), (450, 500)), 29 | mark: "o", 30 | mark-style: (stroke: blue, fill: white), 31 | mark-size: .1, 32 | ) 33 | plot.add( 34 | ((75, 50), (450, 125)), 35 | mark: "o", 36 | style: (stroke: (paint: red, dash: "dashed")), 37 | mark-style: (stroke: red, fill: white), 38 | mark-size: .1, 39 | ) 40 | }, 41 | ) 42 | }) 43 | }, 44 | caption: [Divergent], 45 | ) 46 | ], 47 | [ 48 | #set align(bottom) 49 | #figure( 50 | { 51 | set text(font: "Virgil") 52 | cetz.canvas({ 53 | cetz.draw.set-style(axes: (shared-zero: false)) 54 | 55 | plot.plot( 56 | size: (3, 3), 57 | y-label: [State], 58 | x-label: [Time], 59 | axis-style: "school-book", 60 | legend-style: ( 61 | default-position: "north", 62 | stroke: none, 63 | ), 64 | x-tick-step: none, 65 | y-tick-step: none, 66 | x-min: 0, 67 | x-max: 500, 68 | x-grid: true, 69 | y-min: 0, 70 | y-max: 500, 71 | { 72 | plot.add( 73 | ((75, 125), (450, 300)), 74 | style: (stroke: (paint: red, dash: "dashed")), 75 | mark-style: (stroke: red, fill: white), 76 | mark-size: .1, 77 | mark: "o", 78 | label: "Target", 79 | ) 80 | plot.add( 81 | ((75, 500), (450, 325)), 82 | style: ( 83 | stroke: (paint: blue), 84 | mark: (fill: blue, stroke: blue), 85 | ), 86 | mark-style: (stroke: blue, fill: white), 87 | mark-size: .1, 88 | mark: "o", 89 | label: "Actual", 90 | ) 91 | }, 92 | ) 93 | }) 94 | }, 95 | caption: [Convergent], 96 | ) 97 | ], 98 | [ 99 | #set align(bottom) 100 | #figure( 101 | { 102 | set text(font: "Virgil") 103 | cetz.canvas({ 104 | cetz.draw.set-style(axes: (shared-zero: false)) 105 | 106 | plot.plot( 107 | size: (3, 3), 108 | y-label: [State], 109 | x-label: [Time], 110 | axis-style: "school-book", 111 | x-tick-step: none, 112 | y-tick-step: none, 113 | x-min: 0, 114 | x-max: 500, 115 | x-grid: true, 116 | y-min: 0, 117 | y-max: 500, 118 | legend: "legend.inner-south-east", 119 | { 120 | plot.add( 121 | ((75, 75), (450, 300)), 122 | mark: "o", 123 | mark-style: (stroke: blue, fill: white), 124 | mark-size: .1, 125 | ) 126 | plot.add( 127 | ((75, 50), (450, 275)), 128 | mark: "o", 129 | style: (stroke: (paint: red, dash: "dashed")), 130 | mark-style: (stroke: red, fill: white), 131 | mark-size: .1, 132 | ) 133 | }, 134 | ) 135 | }) 136 | }, 137 | caption: [Congruent], 138 | ) 139 | ], 140 | ) 141 | -------------------------------------------------------------------------------- /src/thesis/theme/UMONS_FS.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 34 | 36 | 42 | 44 | 47 | 48 | 50 | 53 | 54 | 55 | 58 | 62 | 66 | 70 | 74 | 78 | Faculty of sciences 93 | 94 | 95 | -------------------------------------------------------------------------------- /resources/images/inputs-cube-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /resources/graphviz/my-app-not-ok.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | rankdir="BT" 4 | node [ style="filled", margin=.05]; 5 | edge [ dir="back" ]; 6 | ratio=.5 7 | 8 | "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" [label = "python3-3.10.12", fillcolor = "orange", color = "orange"]; 9 | "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8" [label = "bzip2-1.0.8"]; 10 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" [label = "ncurses-6.4"]; 11 | "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" [label = "sqlite-3.43.1", fillcolor = "orange", color = "orange"]; 12 | "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" [label = "readline-8.2p1"]; 13 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" [label = "zlib-1.3", fillcolor = "red", color = "red"]; 14 | "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23" [label = "gdbm-1.23"]; 15 | "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10" [label = "openssl-3.0.10"]; 16 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" [label = "glibc-2.37-8"]; 17 | "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4" [label = "libidn2-2.3.4"]; 18 | "br1p5pan2pgmgrm81kj43qawd9b9nns1-libunistring-1.1" [label = "libunistring-1.1"]; 19 | "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36" [label = "libxcrypt-4.4.36"]; 20 | "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0" [label = "expat-2.5.0"]; 21 | "rfckdjskd983ylf05jm9mlsw7y618hyr-xgcc-12.3.0-libgcc" [label = "xgcc-12.3.0-libgcc"]; 22 | "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4" [label = "xz-5.4.4"]; 23 | "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15" [label = "bash-5.2-p15"]; 24 | "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" [label = "gcc-12.3.0-lib"]; 25 | "xvxaw8q1b4dja27ljmynmc9818aagjz3-gcc-12.3.0-libgcc" [label = "gcc-12.3.0-libgcc"]; 26 | "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4" [label = "libffi-3.4.4"]; 27 | 28 | "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 29 | "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 30 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 31 | "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" [ color = "orange" ]; 32 | "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 33 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" [ color = "orange" ]; 34 | "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 35 | "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 36 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 37 | "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 38 | "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 39 | "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 40 | "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 41 | "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 42 | 43 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4" []; 44 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8" []; 45 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" []; 46 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" -> "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" [ color = "orange" ]; 47 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" []; 48 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" -> "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" []; 49 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" []; 50 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" []; 51 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23" []; 52 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10" []; 53 | "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4" -> "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" []; 54 | "rfckdjskd983ylf05jm9mlsw7y618hyr-xgcc-12.3.0-libgcc" -> "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" []; 55 | "br1p5pan2pgmgrm81kj43qawd9b9nns1-libunistring-1.1" -> "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4" []; 56 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36" []; 57 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0" []; 58 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4" []; 59 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15" []; 60 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" []; 61 | "xvxaw8q1b4dja27ljmynmc9818aagjz3-gcc-12.3.0-libgcc" -> "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" []; 62 | } 63 | -------------------------------------------------------------------------------- /resources/graphviz/python.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | rankdir="BT" 4 | node [ style="filled", margin=.05]; 5 | edge [ dir="back" ]; 6 | ratio=.5 7 | 8 | "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" [label = "python3-3.10.12"]; 9 | "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8" [label = "bzip2-1.0.8"]; 10 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" [label = "ncurses-6.4"]; 11 | "dk5vk3c9zknbjzzxmiglzv46qgv32gb0-tzdata-2023c" [label = "tzdata-2023c"]; 12 | "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" [label = "sqlite-3.43.1"]; 13 | "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" [label = "readline-8.2p1"]; 14 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" [label = "zlib-1.3"]; 15 | "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23" [label = "gdbm-1.23"]; 16 | "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10" [label = "openssl-3.0.10"]; 17 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" [label = "glibc-2.37-8"]; 18 | "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4" [label = "libidn2-2.3.4"]; 19 | "br1p5pan2pgmgrm81kj43qawd9b9nns1-libunistring-1.1" [label = "libunistring-1.1"]; 20 | "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36" [label = "libxcrypt-4.4.36"]; 21 | "pfqk28f0yaq18ha10ri9d3a8z5kv8s6l-mailcap-2.1.53" [label = "mailcap-2.1.53"]; 22 | "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0" [label = "expat-2.5.0"]; 23 | "rfckdjskd983ylf05jm9mlsw7y618hyr-xgcc-12.3.0-libgcc" [label = "xgcc-12.3.0-libgcc"]; 24 | "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4" [label = "xz-5.4.4"]; 25 | "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15" [label = "bash-5.2-p15"]; 26 | "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" [label = "gcc-12.3.0-lib"]; 27 | "xvxaw8q1b4dja27ljmynmc9818aagjz3-gcc-12.3.0-libgcc" [label = "gcc-12.3.0-libgcc"]; 28 | "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4" [label = "libffi-3.4.4"]; 29 | 30 | "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 31 | "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 32 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 33 | "dk5vk3c9zknbjzzxmiglzv46qgv32gb0-tzdata-2023c" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 34 | "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 35 | "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 36 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 37 | "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 38 | "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 39 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 40 | "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 41 | "pfqk28f0yaq18ha10ri9d3a8z5kv8s6l-mailcap-2.1.53" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 42 | "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 43 | "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 44 | "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 45 | "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" -> "pzf6dnxg8gf04xazzjdwarm7s03cbrgz-python3-3.10.12" []; 46 | 47 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "35badg7gpxkhyzcrdyh2dfi9wfd43phz-libffi-3.4.4" []; 48 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "6947mfg2jlid97cnvzvc6cvv6wpj2yhg-bzip2-1.0.8" []; 49 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" []; 50 | "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" -> "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" []; 51 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "fmh3s032bcsbfcdp82zsjlmkj1kp72j6-sqlite-3.43.1" []; 52 | "d48d0ppksa6gwxjlkwf2i93rilyv9jvq-ncurses-6.4" -> "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" []; 53 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "g3dx6xjlvkg2njyxjsx9dswx5wjvkrm5-readline-8.2p1" []; 54 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "ig0kkzw4n2pws12dj7szjm71f1a43if6-zlib-1.3" []; 55 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "jhqflhc7k4jwz5s13cj219pvwywzc6j9-gdbm-1.23" []; 56 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "l7f1pf2dysadqpdxhsb9li01h5jwn5xr-openssl-3.0.10" []; 57 | "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4" -> "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" []; 58 | "rfckdjskd983ylf05jm9mlsw7y618hyr-xgcc-12.3.0-libgcc" -> "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" []; 59 | "br1p5pan2pgmgrm81kj43qawd9b9nns1-libunistring-1.1" -> "8ny01r2xa5mv5brk9srdmv91wrjvxila-libidn2-2.3.4" []; 60 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "ml12av0bi52w2nyrpay8l47xwm1m6i7b-libxcrypt-4.4.36" []; 61 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "q7gkbmmxwai8idqigl9kyv2a7vhppz92-expat-2.5.0" []; 62 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "xa1bg4dk78cx7g9zqqs0akhv0my9l7w5-xz-5.4.4" []; 63 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "xdqlrixlspkks50m9b0mpvag65m3pf2w-bash-5.2-p15" []; 64 | "ld03l52xq2ssn4x0g5asypsxqls40497-glibc-2.37-8" -> "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" []; 65 | "xvxaw8q1b4dja27ljmynmc9818aagjz3-gcc-12.3.0-libgcc" -> "xq05361kqwzcdamcsxr4gzg8ksxrb8sg-gcc-12.3.0-lib" []; 66 | } 67 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-compat": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1696426674, 7 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 8 | "owner": "edolstra", 9 | "repo": "flake-compat", 10 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "edolstra", 15 | "repo": "flake-compat", 16 | "type": "github" 17 | } 18 | }, 19 | "flake-parts": { 20 | "inputs": { 21 | "nixpkgs-lib": "nixpkgs-lib" 22 | }, 23 | "locked": { 24 | "lastModified": 1760948891, 25 | "narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=", 26 | "owner": "hercules-ci", 27 | "repo": "flake-parts", 28 | "rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04", 29 | "type": "github" 30 | }, 31 | "original": { 32 | "owner": "hercules-ci", 33 | "repo": "flake-parts", 34 | "type": "github" 35 | } 36 | }, 37 | "import-tree": { 38 | "locked": { 39 | "lastModified": 1761120675, 40 | "narHash": "sha256-TEbh9zISiQcU82VwVoEbmXHnSGlUxTwvjJA9g9ErSDA=", 41 | "owner": "vic", 42 | "repo": "import-tree", 43 | "rev": "a037ed2a58fc0ebed9e93b9ef79b0646e648f719", 44 | "type": "github" 45 | }, 46 | "original": { 47 | "owner": "vic", 48 | "repo": "import-tree", 49 | "type": "github" 50 | } 51 | }, 52 | "make-shell": { 53 | "inputs": { 54 | "flake-compat": "flake-compat" 55 | }, 56 | "locked": { 57 | "lastModified": 1733933815, 58 | "narHash": "sha256-9JjM7eT66W4NJAXpGUsdyAFXhBxFWR2Z9LZwUa7Hli0=", 59 | "owner": "nicknovitski", 60 | "repo": "make-shell", 61 | "rev": "ffeceae9956df03571ea8e96ef77c2924f13a63c", 62 | "type": "github" 63 | }, 64 | "original": { 65 | "owner": "nicknovitski", 66 | "repo": "make-shell", 67 | "type": "github" 68 | } 69 | }, 70 | "nixpkgs": { 71 | "locked": { 72 | "lastModified": 1761373498, 73 | "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", 74 | "owner": "NixOS", 75 | "repo": "nixpkgs", 76 | "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", 77 | "type": "github" 78 | }, 79 | "original": { 80 | "owner": "NixOS", 81 | "ref": "nixos-unstable", 82 | "repo": "nixpkgs", 83 | "type": "github" 84 | } 85 | }, 86 | "nixpkgs-lib": { 87 | "locked": { 88 | "lastModified": 1754788789, 89 | "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", 90 | "owner": "nix-community", 91 | "repo": "nixpkgs.lib", 92 | "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", 93 | "type": "github" 94 | }, 95 | "original": { 96 | "owner": "nix-community", 97 | "repo": "nixpkgs.lib", 98 | "type": "github" 99 | } 100 | }, 101 | "nixpkgs-unstable": { 102 | "locked": { 103 | "lastModified": 1761349956, 104 | "narHash": "sha256-tH3wHnOJms+U4k/rK2Nn1RfBrhffX92jLP/2VndSn0w=", 105 | "owner": "NixOS", 106 | "repo": "nixpkgs", 107 | "rev": "02f2cb8e0feb4596d20cc52fda73ccee960e3538", 108 | "type": "github" 109 | }, 110 | "original": { 111 | "owner": "NixOS", 112 | "ref": "nixpkgs-unstable", 113 | "repo": "nixpkgs", 114 | "type": "github" 115 | } 116 | }, 117 | "nixpkgs_2": { 118 | "locked": { 119 | "lastModified": 1761236834, 120 | "narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=", 121 | "owner": "nixos", 122 | "repo": "nixpkgs", 123 | "rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1", 124 | "type": "github" 125 | }, 126 | "original": { 127 | "owner": "nixos", 128 | "ref": "nixpkgs-unstable", 129 | "repo": "nixpkgs", 130 | "type": "github" 131 | } 132 | }, 133 | "pkgs-by-name-for-flake-parts": { 134 | "locked": { 135 | "lastModified": 1743779435, 136 | "narHash": "sha256-5eaQ3iKcwUbLw7pOJJqV85qgf5L+ihfsISrifGM7czQ=", 137 | "owner": "drupol", 138 | "repo": "pkgs-by-name-for-flake-parts", 139 | "rev": "477b3e8f981e3d7bac9d297e64796c918942f744", 140 | "type": "github" 141 | }, 142 | "original": { 143 | "owner": "drupol", 144 | "repo": "pkgs-by-name-for-flake-parts", 145 | "type": "github" 146 | } 147 | }, 148 | "root": { 149 | "inputs": { 150 | "flake-parts": "flake-parts", 151 | "import-tree": "import-tree", 152 | "make-shell": "make-shell", 153 | "nixpkgs": "nixpkgs", 154 | "nixpkgs-unstable": "nixpkgs-unstable", 155 | "pkgs-by-name-for-flake-parts": "pkgs-by-name-for-flake-parts", 156 | "systems": "systems", 157 | "treefmt-nix": "treefmt-nix" 158 | } 159 | }, 160 | "systems": { 161 | "locked": { 162 | "lastModified": 1681028828, 163 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 164 | "owner": "nix-systems", 165 | "repo": "default", 166 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 167 | "type": "github" 168 | }, 169 | "original": { 170 | "owner": "nix-systems", 171 | "repo": "default", 172 | "type": "github" 173 | } 174 | }, 175 | "treefmt-nix": { 176 | "inputs": { 177 | "nixpkgs": "nixpkgs_2" 178 | }, 179 | "locked": { 180 | "lastModified": 1761311587, 181 | "narHash": "sha256-Msq86cR5SjozQGCnC6H8C+0cD4rnx91BPltZ9KK613Y=", 182 | "owner": "numtide", 183 | "repo": "treefmt-nix", 184 | "rev": "2eddae033e4e74bf581c2d1dfa101f9033dbd2dc", 185 | "type": "github" 186 | }, 187 | "original": { 188 | "owner": "numtide", 189 | "repo": "treefmt-nix", 190 | "type": "github" 191 | } 192 | } 193 | }, 194 | "root": "root", 195 | "version": 7 196 | } 197 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Download latest](https://img.shields.io/badge/Download-Latest-brightgreen?style=flat-square)](https://github.com/drupol/master-thesis/releases/latest) 2 | [![CC BY License badge](https://img.shields.io/badge/License-CC--BY--4.0-brightgreen?style=flat-square)](https://creativecommons.org/licenses/by/4.0/) 3 | [![HL3 License badge](https://img.shields.io/badge/License-HL3--full-brightgreen?style=flat-square)](https://firstdonoharm.dev/version/3/0/full.html) 4 | [![Static Badge](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.12666898-brightgreen?style=flat-square)](https://doi.org/10.5281/zenodo.12666898) 5 | 6 | # Reproducibility in Software Engineering (RiSE) 7 | 8 | This repository contains the sources of my master's thesis in computer science, 9 | entitled "Reproducibility in Software Engineering", that was completed in June 10 | 2024 at the [University Of Mons] under the supervision of Professor [Tom Mens], 11 | director of the [Software Engineering Lab]. 12 | 13 | Founded in October 2003, the [Software Engineering Lab] carries out research in 14 | the domains of open source software, empirical software engineering, software 15 | ecosystems, software evolution, and software modeling. The lab is directed by 16 | Professor [Tom Mens], and is part of the [Department of Computer Science] of the 17 | Faculty of Sciences of the [University of Mons], Belgium. 18 | 19 | ## Abstract 20 | 21 | The concept of reproducibility has long been a cornerstone in scientific 22 | research, ensuring that results are robust, repeatable, and can be independently 23 | verified. This concept has been extended to computer science, focusing on the 24 | ability to recreate identical software artefacts. However, the importance of 25 | reproducibility in software engineering is often overlooked, leading to 26 | challenges in the validation, security, and reliability of software products. 27 | 28 | This master's thesis aims to investigate the current state of reproducibility in 29 | software engineering, exploring both the barriers and potential solutions to 30 | making software more reproducible and raising awareness. It identifies key 31 | factors that impede reproducibility such as inconsistent environments, lack of 32 | standardisation, and incomplete documentation. To tackle these issues, I propose 33 | an empirical comparison of tools facilitating software reproducibility. 34 | 35 | To provide a comprehensive assessment of reproducibility in software 36 | engineering, this study adopts a methodology that involves a hands-on evaluation 37 | of four different methods and tools. Through a systematic evaluation of these 38 | tools, this research seeks to determine their effectiveness in establishing and 39 | maintaining identical software environments and builds. 40 | 41 | This study contributes to academic knowledge and offers practical insights that 42 | could influence future software development protocols and standards. 43 | 44 | ## Repository Structure 45 | 46 | The repository is structured as follows: 47 | 48 | - `src/thesis`: Contains the [Typst] source code 49 | - `nix`: Contains the [Nix] expressions necessary for the build but also for the 50 | local development environment 51 | - `resources`: Contains some resources (images, source code, ...) 52 | 53 | ## Licensing 54 | 55 | This work is licenced under a dual license: the Creative Commons Attribution 4.0 56 | International ([CC BY 4.0]) and the Hippocratic Licence 3.0 ([HL3]) licences. 57 | You are free to share and adapt the material under the terms of the CC BY 4.0, 58 | provided you give appropriate credit to the original author. You must also use 59 | the material in accordance with the ethical guidelines specified in HL3, 60 | ensuring it is not used to contribute to human rights abuses or other unethical 61 | practices. In case of any conflict between the licences, HL3 will take 62 | precedence. 63 | 64 | ## Cite 65 | 66 | ``` 67 | @masterthesis{dellaieraMasterThesis2024, 68 | title = {Reproducibility in Software Engineering}, 69 | author = {Dellaiera, Pol}, 70 | year = 2024, 71 | month = {June}, 72 | school = {University of Mons}, 73 | address = {Mons, Belgium}, 74 | type = {Master's thesis}, 75 | doi = {10.5281/zenodo.12666898} 76 | } 77 | ``` 78 | 79 | ## How To Contribute 80 | 81 | I welcome and appreciate contributions from the community! Here are the ways you 82 | can contribute: 83 | 84 | 1. **Codeberg (Preferred)** 85 | - Visit the main repository on Codeberg: 86 | https://codeberg.org/p1ld7a/master-thesis 87 | - Fork the repository and make your changes. 88 | - Submit a pull request for review. 89 | - Ensure your code adheres to our coding guidelines and is well-documented. 90 | 91 | 2. **GitHub** 92 | - Visit the mirror repository on GitHub: 93 | https://github.com/drupol/master-thesis 94 | - Fork the repository and make your changes. 95 | - Submit a pull request for review. 96 | - Ensure your code adheres to our coding guidelines and is well-documented. 97 | 98 | 3. **Email** 99 | - If you prefer, you can also contribute by sending me patches or suggestions 100 | via email. 101 | - Please include a detailed description of your changes and any relevant 102 | attachments. 103 | - My email address: pol.dellaiera@protonmail.com 104 | 105 | ### Contribution Guidelines 106 | 107 | To ensure a smooth contribution process, please follow these guidelines: 108 | 109 | - **Code Quality:** Make sure your changes are clean and readable. 110 | - **Commit Messages:** Write clear and descriptive commit messages. 111 | 112 | ### Setting Up Your Development Environment 113 | 114 | To set up a local development environment with all the necessary tools to build 115 | the document, you have two options: 116 | 117 | 1. **Using Nix:** Load the default shell environment by running: `nix develop` 118 | 119 | 2. **Using DevContainer:** You can also set up a complete development 120 | environment using [DevContainer]. 121 | 122 | The master thesis is written using [Typst], a modern typesetting system. The 123 | primary language of the document is British English. 124 | 125 | [DevContainer]: https://containers.dev/ 126 | [Nix]: https://nixos.org/ 127 | [Typst]: https://typst.app/ 128 | [University Of Mons]: https://www.umons.ac.be/ 129 | [Tom Mens]: https://staff.umons.ac.be/tom.mens/ 130 | [CC BY 4.0]: https://creativecommons.org/licenses/by/4.0/ 131 | [HL3]: https://firstdonoharm.dev/version/3/0/full.html 132 | [Software Engineering Lab]: https://informatique-umons.be/genlog/ 133 | [Department of Computer Science]: https://informatique.umons.ac.be/ 134 | -------------------------------------------------------------------------------- /resources/images/inputs-cube-3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/thesis/theme/template.typ: -------------------------------------------------------------------------------- 1 | #import "../imports/preamble.typ": * 2 | #import "common/metadata.typ": * 3 | #import "common/titlepage.typ": * 4 | #import "disclaimer.typ": * 5 | #import "leftblank.typ": * 6 | #import "acknowledgement.typ": * 7 | #import "abstract.typ": * 8 | #import selectors: * 9 | 10 | #let getHeader() = { 11 | context { 12 | let page-counter = counter(page) 13 | let current = page-counter.at(here()).first() 14 | 15 | let chapter = hydra( 16 | 1, 17 | display: (_, it) => { 18 | if it.numbering != none { 19 | [#numbering(it.numbering, ..counter(heading).at(it.location())) - #it.body] 20 | } 21 | }, 22 | ) 23 | 24 | let section = hydra(selectors.by-level(min: 2), display: ( 25 | _context, 26 | element, 27 | ) => element.body) 28 | let items = (smallcaps(chapter), h(1fr), emph(section)) 29 | 30 | if calc.even(current) { 31 | items.rev() 32 | } else { 33 | items 34 | }.join() 35 | 36 | if (chapter != none) { 37 | [#line(length: 100%, stroke: .2pt + rgb("#000000").lighten(65%))] 38 | } 39 | } 40 | } 41 | 42 | #let getFooter() = { 43 | context { 44 | let page-counter = counter(page) 45 | let current = page-counter.at(here()).first() 46 | let items = ([#current], h(1fr), emph(title)) 47 | 48 | if calc.even(current) { 49 | items 50 | } else { 51 | items.rev() 52 | }.join() 53 | } 54 | } 55 | 56 | #let chapterquote( 57 | title: none, 58 | ref: none, 59 | quoteText: none, 60 | quoteAttribution: none, 61 | ) = { 62 | pagebreak() 63 | 64 | place(top + left, dx: 45pt, dy: 45pt)[ 65 | #rect(width: 50pt, height: 50pt, fill: rgb(125, 125, 125)) 66 | ] 67 | 68 | place(top + left)[ 69 | #rect(width: 70pt, height: 70pt, fill: rgb(0, 0, 0)) 70 | ] 71 | 72 | v(10%) 73 | 74 | [ 75 | #{ 76 | heading(title, level: 1) 77 | } 78 | #label(ref) 79 | ] 80 | 81 | if quoteText != none { 82 | show quote: set pad(x: 0em) 83 | quote( 84 | block: true, 85 | attribution: [#{ 86 | if quoteAttribution != none { 87 | cite(form: "prose", quoteAttribution) 88 | } 89 | }], 90 | quoteText, 91 | ) 92 | } 93 | 94 | pagebreak() 95 | } 96 | 97 | #let project( 98 | title: "", 99 | university: "", 100 | faculty: "", 101 | degree: "", 102 | program: "", 103 | supervisor: "", 104 | advisors: (), 105 | author: "", 106 | doi: none, 107 | startDate: none, 108 | submissionDate: none, 109 | disclaimer: none, 110 | acknowledgement: none, 111 | abstract: none, 112 | accessibility: none, 113 | extra: none, 114 | terms: (), 115 | body, 116 | ) = { 117 | register-glossary(terms) 118 | 119 | // --- Page configuration --- 120 | set page( 121 | margin: page-margin, 122 | numbering: "1", 123 | number-align: center, 124 | header: getHeader(), 125 | footer: getFooter(), 126 | paper: "a4", 127 | ) 128 | 129 | titlepage( 130 | title: title, 131 | subtitle: subtitle, 132 | university: university, 133 | faculty: faculty, 134 | degree: degree, 135 | program: program, 136 | supervisor: supervisor, 137 | advisors: advisors, 138 | author: author, 139 | authorOrcId: authorOrcId, 140 | startDate: startDate, 141 | submissionDate: submissionDate, 142 | rev: rev, 143 | shortRev: shortRev, 144 | builddate: builddate, 145 | doi: doi, 146 | ) 147 | 148 | // --- Typography --- 149 | set text( 150 | font: body-font, 151 | size: font.normal, 152 | lang: "en", 153 | hyphenate: false, 154 | ) 155 | 156 | // --- Paragraphs --- 157 | // Source: https://typst.app/docs/guides/guide-for-latex-users/ 158 | set par(justify: true) 159 | set par(spacing: 1em) 160 | 161 | show ref: it => { 162 | let el = it.element 163 | 164 | if el == none { 165 | return it 166 | } 167 | 168 | if el.has("level") and el.level == 1 { 169 | let (chapter,) = counter(heading).at(el.label) 170 | link(el.label)[Chapter #chapter] 171 | } else if el.has("level") and el.level == 2 { 172 | let (chapter, section) = counter(heading).at(el.label) 173 | link(el.label)[Chapter #chapter, section #section] 174 | } else if el.has("level") and el.level == 3 { 175 | let (chapter, section, subsection) = counter(heading).at(el.label) 176 | link(el.label)[Chapter #chapter, section #section.#subsection] 177 | } else if el.has("level") and el.level == 4 { 178 | let ( 179 | chapter, 180 | section, 181 | subsection, 182 | subsubsection, 183 | ) = counter(heading).at(el.label) 184 | link( 185 | el.label, 186 | )[Chapter #chapter, subsection #section.#subsection.#subsubsection] 187 | } else { 188 | link(el.label)[#it] 189 | } 190 | } 191 | 192 | // --- Citations --- 193 | set cite( 194 | form: "prose", 195 | style: "ieee", 196 | ) 197 | show cite: cite => { 198 | underline(cite, stroke: .2pt + rgb("#000000").lighten(65%)) 199 | } 200 | 201 | // --- Links --- 202 | show link: it => { 203 | underline(it, stroke: .2pt + rgb("#000000").lighten(65%)) 204 | } 205 | 206 | leftblank(weak: false) 207 | [#disclaimer] 208 | leftblank(weak: false) 209 | [#abstract] 210 | leftblank(weak: false) 211 | [#acknowledgement] 212 | leftblank(weak: false) 213 | [#accessibility] 214 | [#extra] 215 | { 216 | pagebreak(weak: true) 217 | 218 | [ 219 | #{ 220 | heading(level: 1, "Glossary", outlined: false) 221 | } 222 | ] 223 | 224 | v(10mm) 225 | 226 | // FIX left alignment of glossary: 227 | // With glossary 0.5.1 it is necessary 228 | // to overwrite figure captions to be aligned left 229 | show figure.caption: c => block(width: 100%, align(left, c.body)) 230 | 231 | print-glossary(show-all: true, terms) 232 | } 233 | 234 | leftblank(weak: false) 235 | 236 | { 237 | // --- Table of Contents --- 238 | { 239 | set par( 240 | leading: 0.4em, 241 | justify: true, 242 | ) 243 | show outline.entry.where(level: 1): it => { 244 | v(12pt, weak: true) 245 | strong(it) 246 | } 247 | 248 | heading(numbering: none, outlined: false)[Contents] 249 | outline(title: "", indent: 1.5em, depth: 3) 250 | } 251 | 252 | leftblank(weak: false) 253 | 254 | // --- Headings --- 255 | set heading(numbering: "1.") 256 | show heading.where(level: 1): set heading( 257 | numbering: "I", 258 | supplement: [Chapter], 259 | ) 260 | show heading.where(level: 2): set heading( 261 | numbering: "1.", 262 | supplement: [Section], 263 | ) 264 | show heading.where(level: 3): set heading( 265 | numbering: "1.", 266 | supplement: [Subsection], 267 | ) 268 | show heading.where(level: 1): it => block({ 269 | set text( 270 | 2em, 271 | weight: "bold", 272 | ) 273 | v(8em) 274 | if it.numbering != none [ 275 | Chapter #numbering(it.numbering, ..counter(heading).at(it.location())) 276 | #v(.5em) 277 | ] 278 | it.body 279 | v(0.5em) 280 | }) 281 | 282 | // --- Various outlines --- 283 | show outline.entry.where(level: 1): it => { 284 | v(1em, weak: true) 285 | it 286 | } 287 | 288 | // --- Figures --- 289 | show figure.caption: it => ( 290 | context [*#it.supplement #it.counter.display()*: #it.body] 291 | ) 292 | show figure.where(kind: "table"): set figure.caption(position: top) 293 | body 294 | } 295 | 296 | { 297 | set par( 298 | leading: 1em, 299 | justify: true, 300 | ) 301 | 302 | // List of definitions. 303 | [#heading(numbering: none)[List of definitions] #label( 304 | "list-of-definitions", 305 | )] 306 | outline(title: "", target: figure.where(kind: "definition")) 307 | 308 | leftblank(weak: false) 309 | 310 | // List of figures. 311 | pagebreak() 312 | [#heading(numbering: none)[List of figures] #label("list-of-figures")] 313 | outline(title: "", target: figure.where(kind: image)) 314 | 315 | leftblank(weak: false) 316 | 317 | // List of tables. 318 | pagebreak() 319 | [#heading(numbering: none)[List of tables] #label("list-of-tables")] 320 | outline(title: "", target: figure.where(kind: "table")) 321 | 322 | leftblank(weak: false) 323 | 324 | [#heading("Bibliography", level: 1, outlined: true) #label("bibliography")] 325 | bibliography("../literature.bib", full: true, style: "ieee", title: none) 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /src/thesis/main.typ: -------------------------------------------------------------------------------- 1 | #import "imports/preamble.typ": * 2 | #import "theme/template.typ": * 3 | 4 | #set document(title: title, author: author, date: none, keywords: ( 5 | "university", 6 | "umons", 7 | "june 2024", 8 | "master thesis", 9 | "reproducibility", 10 | "r13y", 11 | "compilation", 12 | "docker", 13 | "nix", 14 | "guix", 15 | )) 16 | 17 | #show: make-glossary 18 | 19 | #show: project.with( 20 | title: title, 21 | university: university, 22 | faculty: faculty, 23 | degree: degree, 24 | program: program, 25 | supervisor: supervisor, 26 | advisors: advisors, 27 | author: author, 28 | startDate: startDate, 29 | submissionDate: submissionDate, 30 | doi: doi, 31 | disclaimer: include "disclaimer.typ", 32 | acknowledgement: include "acknowledgement.typ", 33 | abstract: include "abstract.typ", 34 | accessibility: include "accessibility.typ", 35 | extra: include "extra.typ", 36 | terms: ( 37 | ( 38 | key: "CC BY 4.0", 39 | short: "CC BY 4.0", 40 | long: "Creative Commons Attribution 4.0 International", 41 | description: [The Creative Commons Attribution 4.0 International Licence #cite(, form: "normal") is a widely used licence that allows others to distribute, remix, adapt, and build upon your work, even commercially, as long as they credit you for the original creation. This is the most flexible of the CC licences.], 42 | ), 43 | ( 44 | key: "CDN", 45 | short: "CDN", 46 | long: "Content Delivery Network", 47 | description: [A content delivery network is a system of distributed servers that deliver web content to a user based on the geographic locations of the user, the origin of the webpage and a content delivery server, making the delivery of content more efficient.], 48 | ), 49 | ( 50 | key: "CICD", 51 | short: "CI/CD", 52 | long: "Continuous Integration/Continuous Deployment", 53 | description: [Continuous Integration (CI) is a software development practice where developers regularly merge their code changes into a central repository, after which automated builds and tests are run. Continuous Deployment (CD) is a software release process that uses automated testing to validate that changes are safe to deploy to production.], 54 | ), 55 | ( 56 | key: "CPU", 57 | short: "CPU", 58 | long: "Central Processing Unit", 59 | description: [The CPU is the primary component of a computer that processes instructions. It runs the operating system and applications, constantly receiving input from the user or active software programs. It processes the data and produces outputs. ARM and X86 are two common CPU architectures.], 60 | ), 61 | ( 62 | key: "CRA", 63 | short: "CRA", 64 | long: "Cyber Resilience Act", 65 | description: [The Cyber Resilience Act #cite(, form: "normal") is a proposed European Union regulation that aims to improve the cybersecurity of digital products and services. It includes provisions for #link()[software supply chain] security, incident reporting, and security certification.], 66 | ), 67 | ( 68 | key: "CS", 69 | short: "CS", 70 | long: "Computer Science", 71 | description: [The discipline of Computer Science includes the study of algorithms and data structures, computer and network design, modelling data and information processes, and artificial intelligence. Computer Science draws some of its foundations from mathematics and engineering and therefore incorporates techniques from areas such as queueing theory, probability and statistics, and electronic circuit design.], 72 | ), 73 | ( 74 | key: "CycloneDX", 75 | short: "CycloneDX", 76 | description: [@cyclonedx is an open-format standard backed by the OWASP foundation and Ecma Technical Committee designed to provide comprehensive and interoperable information about the components used within software projects like software bill of materials and advanced supply chain capabilities for cyber risk reduction.], 77 | ), 78 | ( 79 | key: "DevOps", 80 | short: "DevOps", 81 | description: [DevOps is a set of practices that combines software development (Dev) and IT operations (Ops). It aims to shorten the systems development life cycle and provide #gls("CICD").], 82 | ), 83 | ( 84 | key: "DevSecOps", 85 | short: "DevSecOps", 86 | description: [ 87 | DevSecOps is an extension of #gls("DevOps") practices that integrates security (Sec) measures at every stage of the software development lifecycle, ensuring that security is a fundamental aspect of development and operations processes. 88 | ], 89 | ), 90 | ( 91 | key: "DSL", 92 | short: "DSL", 93 | long: "Domain Specific Language", 94 | description: [A domain-specific language is a computer language specialised to a particular application domain. This is in contrast to a general-purpose language, which is broadly applicable across various domains.], 95 | ), 96 | ( 97 | key: "FHS", 98 | short: "FHS", 99 | long: "Filesystem Hierarchy Standard", 100 | description: [The Filesystem Hierarchy Standard is a reference document that describe the conventions used for the layout of Unix-like operating systems. This includes names, locations, and permissions of many file and directories.], 101 | ), 102 | ( 103 | key: "HL3", 104 | short: "HL3", 105 | long: "Hippocratic Licence 3.0", 106 | description: [The Hippocratic Licence 3.0 #cite(, form: "normal") is a software license that ensures that software is not used to contribute to human rights abuses or other unethical practices. It is designed to protect users and communities from the potential misuse of software.], 107 | ), 108 | ( 109 | key: "IDE", 110 | short: "IDE", 111 | long: "Integrated Development Environment", 112 | plural: "IDEs", 113 | longplural: "Integrated Development Environments", 114 | description: [An integrated development environment is a software application that provides comprehensive facilities to computer programmers for software development.], 115 | ), 116 | ( 117 | key: "IEEE", 118 | short: "IEEE", 119 | long: "Institute of Electrical and Electronics Engineers", 120 | description: [The Institute of Electrical and Electronics Engineers #cite(, form: "normal"), established in 1963, is the world's largest technical professional organisation dedicated to advancing technology for the benefit of humanity. It serves as a professional association for electronic engineering, electrical engineering, and related disciplines.], 121 | ), 122 | ( 123 | key: "MD5", 124 | short: "MD5", 125 | long: "Message Digest 5", 126 | description: [The MD5 message-digest algorithm is a widely used hash function producing a 128-bit hash value. MD5 was designed by Ronald Rivest in 1991 to replace an earlier hash function MD4, and was specified in 1992 as RFC 1321.], 127 | ), 128 | ( 129 | key: "OCI", 130 | short: "OCI", 131 | long: "Open Container Initiative", 132 | description: [OCI stands for @opencontainerinitiative, an open governance project for the purpose of creating open industry standards around container formats and runtime. An "OCI image" is a container image that conforms to the OCI image format specification.], 133 | ), 134 | ( 135 | key: "OS", 136 | short: "OS", 137 | long: "Operating System", 138 | plural: "OSes", 139 | longplural: "Operating Systems", 140 | description: [An operating system is system software that manages computer hardware and software resources, and provides common services for computer programs.], 141 | ), 142 | ( 143 | key: "PDF", 144 | short: "PDF", 145 | long: "Portable Document Format", 146 | description: [A file format developed by Adobe in the 1990s to present documents, including text formatting and images, in a manner independent of application software, hardware, and operating systems.], 147 | ), 148 | ( 149 | key: "POSIX", 150 | short: "POSIX", 151 | long: "Portable Operating System Interface", 152 | description: [POSIX is a family of standards specified by the #gls("IEEE") for maintaining compatibility between operating systems.], 153 | ), 154 | ( 155 | key: "PURL", 156 | short: "PURL", 157 | plural: "PURLs", 158 | long: "Package URL", 159 | description: [A PURL #cite(, form: "normal") is a #gls("URL") string used to identify and locate a software package in a mostly universal and uniform way across programing languages, package managers, packaging conventions, tools, APIs and databases.], 160 | ), 161 | ( 162 | key: "REPL", 163 | short: "REPL", 164 | long: "Read-Eval-Print Loop", 165 | description: [A read-eval-print loop is an interactive computer programming environment that takes single user inputs, evaluates them, and returns the result to the user.], 166 | ), 167 | ( 168 | key: "SBOM", 169 | short: "SBOM", 170 | plural: "SBOMs", 171 | long: "Software Bill of Materials", 172 | description: [The software bill of materials is a comprehensive inventory of all components, including libraries, dependencies and versions, that constitute a software product, used for tracking and managing software supply chain security.], 173 | ), 174 | ( 175 | key: "SPDX", 176 | short: "SPDX", 177 | long: "Software Package Data Exchange", 178 | description: [The @spdx format, created and maintained by the 179 | Linux Foundation, is a standardised way of documenting and communicating the 180 | components, licenses, and copyrights of software packages. It provides a 181 | consistent method for tracking and sharing information about software contents, 182 | particularly in open-source and collaborative environments.], 183 | ), 184 | ( 185 | key: "SHA1", 186 | short: "SHA-1", 187 | long: "Secure Hash Algorithm 1", 188 | description: [SHA-1 is a hash function which takes an input and produces a 160-bit (20-byte) hash value known as a message digest – typically rendered as 40 hexadecimal digits. It was designed by the United States National Security Agency (NSA), and is a U.S. Federal Information Processing Standard.], 189 | ), 190 | ( 191 | key: "SHA2", 192 | short: "SHA-2", 193 | long: "Secure Hash Algorithm 2", 194 | description: [SHA-2 is a set of cryptographic hash functions designed by the United States National Security Agency (NSA). It consists of six hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256.], 195 | ), 196 | ( 197 | key: "SE", 198 | short: "SE", 199 | long: "Software Engineering", 200 | description: [Software Engineering is a computing discipline. It is the systematic application of engineering approaches to the development of software.], 201 | ), 202 | ( 203 | key: "SemVer", 204 | short: "SemVer", 205 | long: "Semantic Versioning", 206 | description: [Semantic Versioning #cite(, form: "normal") is a versioning scheme for software that uses a three-part version number: `MAJOR.MINOR.PATCH`.], 207 | ), 208 | ( 209 | key: "SRI", 210 | short: "SRI", 211 | long: "Subresource Integrity", 212 | description: [Subresource Integrity #cite(, form: "normal") is a security feature that allows web developers to ensure that resources they fetch are delivered without unexpected manipulation.], 213 | ), 214 | ( 215 | key: "SVG", 216 | short: "SVG", 217 | long: "Scalable Vector Graphics", 218 | description: [SVG is an XML-based vector image format.], 219 | ), 220 | ( 221 | key: "SWHID", 222 | short: "SWHID", 223 | long: "Software Heritage Identifier", 224 | description: [The Software Heritage Identifier #cite(, form: "normal") is a unique identifier for software artifacts, such as source code, that is used to track and reference software across different platforms and systems.], 225 | ), 226 | ( 227 | key: "URL", 228 | short: "URL", 229 | long: "Uniform Resource Locator", 230 | description: [A URL is a reference to a web resource that specifies its location on a computer network and a mechanism for retrieving it.], 231 | ), 232 | ), 233 | ) 234 | 235 | #include "1-introduction.typ" 236 | 237 | #include "2-reproducibility.typ" 238 | 239 | #leftblank(weak: false) 240 | 241 | #include "3-tools.typ" 242 | 243 | #include "4-conclusion.typ" 244 | -------------------------------------------------------------------------------- /resources/images/inputs-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 17 | --------------------------------------------------------------------------------