% GHCup % Julian Ospald % June 07, 2024 # GHCup ## What is GHCup? ![](what.jpg) ## State of 2019 ::: incremental * stack is the only "Haskell Installer" * no unified alternative for cabal users * distro packages, nix, manual installs, ... * 🤮 ::: ## How it started ::: incremental * 🤹 small team at work (Capital Match), using different platforms - originally used stack - cabal distro packages constantly out of date * 🦾 first version was 165 LOC - Posix shell * ![](linux.png){#id .class height=32px} only supported linux and mac * ![](rust.png){#id .class height=32px} inspired by **rustup** ::: ## GHCup today ::: incremental * [Haskell Survey 2022](https://taylor.fausak.me/2022/11/18/haskell-survey-results/#s2q1) * ![](survey.png) - over **17k** LOC Haskell - supports all platforms: Linux, Windows, macOS, FreeBSD ::: ## GHCup and haskell.org ::: incremental * the default installer - ![](downloads.png) * provides infrastructure (home page, downloads) ::: ## GHCup and the Haskell Foundation ::: incremental * affiliation: [https://haskell.foundation/affiliates/](https://haskell.foundation/affiliates/) * pays for CI * pays consultants to assist the project ::: ## What is a good installer? ::: incremental * it installs (just that) - everywhere * intuitive interface - `ghcup install ghc` * good documentation - but you shouldn't have to read it * get out of the way - has no self-fulfilling purpose ::: ## Goals and principles ::: incremental - ☮️ unification - unix principles - 🛠️ do one thing and do it well - ⚗️ pipes, compose stdout and stdin (re-usable) - 🎁 good re-distribution - 🛣️ user experience ::: ## What is GHCup (simplified)? ```sh curl -s -L 'https://downloads.haskell.org/~ghc/9.6.5/ghc-9.6.5-x86_64-fedora33-linux.tar.xz' | tar -xJ -C /tmp && cd /tmp/ghc-9.6.5-x86_64-unknown-linux/ && ./configure --prefix="$HOME/.local" && make install && rm -rf /tmp/ghc-9.6.5-x86_64-unknown-linux/ ``` ## What is GHCup really? * [https://hasufell.github.io/posts/2023-11-14-ghcup-is-not-an-installer.html](https://hasufell.github.io/posts/2023-11-14-ghcup-is-not-an-installer.html) ::: incremental * ![](open-box.png){#id .class width=32 height=32px} installer * ![](debian.png){#id .class width=32 height=32px} distribution channel * ![](feedback.png){#id .class width=32 height=32px} feedback channel * ![](qa.png){#id .class width=32 height=32px} testing/QA gateway * ![](user.png){#id .class width=32 height=32px} provider of sane defaults (e.g. "recommended" GHC version) * ![](chain-saw.png){#id .class width=32 height=32px} glue for holistic toolchain experience - VSCode, stack, cabal-install integration * ![](ghaction.png){#id .class width=32 height=32px} CI provisioning (e.g. github actions) ::: ## Upstream Supported tools/dependencies: ::: incremental - GHC - Cabal - HLS - Stack ::: ## Downstream Users: ::: incremental - ![](haskell_logo.png){#id .class height=32px} Haskell developers - beginners, advanced, students, companies - ![](person.png){#id .class width=32 height=32px} end users (e.g. compiling pandoc from source) - ![](ghaction.png){#id .class width=32 height=32px} GitHub CI - GitHub images, Haskell repos - 🪞 mirrors - [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup) - 🧰 tools - [vscode-haskell](https://github.com/haskell/vscode-haskell), [Haskell playground](https://play.haskell.org/), [nvim-lsp-installer](https://github.com/williamboman/nvim-lsp-installer) ::: ## How does it work? ::: incremental * **Architectural components** - ![](sh-file.png){#id .class height=32px} bootstrap scripts - ![](exe-file.png){#id .class height=32px} ghcup binary (compiled) - ![](config-file.png){#id .class height=32px} ghcup-metadata (configuration files) * **Logical components** - ![](terminal.png){#id .class height=32px} cli interface - ![](file.png){#id .class height=32px} file layout / installation destination - ![](tar.png){#id .class height=32px} bindist selection - ![](brick-final-clearbg.png){#id .class height=32px} tui interface ::: ## Basic CLI ::: incremental * show all available tools / versions ```sh ghcup list ``` * install a tool ```sh ghcup install ghc latest ``` * make a tool version the default ```sh ghcup set ghc latest ``` * remove a tool version ```sh ghcup rm ghc 9.10.1 ``` ::: ## Where does it install? ::: incremental * root dir ```sh $ ls ~/.ghcup 📁bin 📁ghc 📁hls 📁cache 📁db 📁logs 📁tmp 🗑️trash 📄config.yaml 📄env ``` * GHC and HLS are installed into sub-directories ```sh $ ls ~/.ghcup/ghc 📁8.10.7 📁9.0.2 📁9.2.8 ``` * bin directory is mostly symbolic links (compare with [update-alternatives](https://man7.org/linux/man-pages/man1/update-alternatives.1.html)) ```sh $ ls ~/.ghcup/bin 📄ghcup 🔗cabal 📄cabal-3.10.3.0 🔗ghc 🔗ghc-8.10 🔗ghc-8.10.7 🔗ghc-9.0 🔗ghc-9.0.2 🔗ghc-9.2 🔗ghc-9.2.8 ``` ::: ## Bindist selection * TODO