Haskeller のための開発環境構築 on GitHub Codespaces

Haskell の開発環境を GitHub Codespaces に構築するためのチュートリアル記事です。
Codespaces の Ubuntu 22.04 コンテナに [ghcup](https://www.haskell.org/ghcup/), [stack](https://docs.haskellstack.org/en/stable/), [Haskell Language Server](https://haskell-language-server.readthedocs.io/en/latest/), [Haskell VSCode Extension](https://marketplace.visualstudio.com/items?itemName=haskell.haskell) がインストールされた状態で開発を始めることができます。

記事内で紹介する設定ファイルは次の repository にも置いてあります。
https://github.com/algas/codespaces-haskell-init

## 対象読者

- オンラインで Haskell を使った開発をしたい
- Haskell の開発環境を構築するのが面倒

## 前提条件

- VSCode を使ったことがある/使っている
- GitHub の基本的な使い方を知っている
- GitHub で Codespaces が使える状態になっている
- Haskell で `cabal` もしくは `stack` コマンドの簡単な使い方を把握している

本記事では VSCode, GitHub Codespaces, Haskell の詳しい説明はしません。

## 3分で始める環境構築

時間がない人のために開発環境の構築方法を説明します。
Codespaces を作るボタンを押すまでは3分もかからないはずです。
(Codespaces コンテナのビルドに数分程度かかることがあります)

1. GitHub repository を作る
開発用の GitHub repository を作成します
1. devcontainer ファイルを git commit & push する
[.devcontainer/devcontainer.json](https://github.com/algas/codespaces-haskell-init/blob/main/.devcontainer/devcontainer.json) と [.devcontainer/Dockerfile](https://github.com/algas/codespaces-haskell-init/blob/main/.devcontainer/Dockerfile)
を先ほど作った repository に置きます
1. GitHub Codespaces を作る
GitHub repository ページの `code` ボタンの `Codespaces` タブにある `Create codespace on main` を押します 
https://docs.github.com/en/codespaces/developing-in-codespaces/creating-a-codespace

数分間待つと Codespaces が立ち上がります。Codespaces が立ち上がったらすぐに開発を始められます。
`cabal init` や `stack new` コマンドなどで Haskell のプロジェクトを作りましょう。

## 設定の解説

本記事で設定したファイルの内容を解説します。

### devcontainer.json

```json
{
  "name": "Ubuntu",
  "build": {
    "dockerfile": "Dockerfile",
    "args": {
      "VARIANT": "ubuntu-22.04"
    }
  },
  "extensions": [
    "haskell.haskell"
  ],
  "remoteUser": "vscode"
}
```

- name: コンテナの名前
- build: コンテナのビルド設定
- extensions: VSCode 拡張機能
- remoteUser: コンテナユーザ名

### Dockerfile

```Dockerfile
# OS
ARG VARIANT="ubuntu-22.04"
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
# avoid interactive mode when installing packages
ENV DEBIAN_FRONTEND=noninteractive
# avoid interactive mode when installing ghcup
ENV BOOTSTRAP_HASKELL_NONINTERACTIVE=1
# GHC version
ENV BOOTSTRAP_HASKELL_GHC_VERSION=9.0.2
# Cabal version
ENV BOOTSTRAP_HASKELL_CABAL_VERSION=3.4.1.0
# install stack
ENV BOOTSTRAP_HASKELL_INSTALL_STACK=1
# install haskell language server
ENV BOOTSTRAP_HASKELL_INSTALL_HLS=1
# OS packages for ghcup
RUN apt-get update && \
    apt-get -y install --no-install-recommends git sudo jq bc make automake rsync htop curl build-essential lsb-release pkg-config libffi-dev libgmp-dev software-properties-common libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf && \
    apt-get clean
# change user
USER vscode
# install ghcup
RUN bash -c "curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh"
# set PATH
ENV PATH=${PATH}:/home/vscode/.local/bin
ENV PATH=${PATH}:/home/vscode/.ghcup/bin
```

Ubuntu-22.04 の VSCode 用イメージをベースにしています。
GHC, CABAL のバージョンを明示しています。
stack, HLS(Haskell Language Server) とともに ghcup をインストールしています。

HLS などを使いたくない場合には VSCode の設定で extension を無効にするか上記の設定ファイルを編集することで削除できます。

## オススメの追加設定

開発環境をより良くするために追加の設定ができます。特にコンテナの自動ビルドを設定することを強くオススメします。

- コンテナの自動ビルド
毎回実行するたびに codespaces のコンテナのビルドが実行されると起動に時間がかかります。コンテナの自動ビルドを設定することで codespaces が起動する時間を短縮できます。GitHub repository の `settings` から `Codespaces` のタブを選択します。`branch` で `main` を選び `Create` ボタンを押すだけで設定完了です。
https://docs.github.com/ja/codespaces/prebuilding-your-codespaces/configuring-prebuilds
- Shell の変更
自分の好みの shell を使えます。`devcontainer.json` で `settings` に `terminal.integrated.defaultProfile.linux` に shell を設定します。
```json
{
  "settings": {
    "terminal.integrated.defaultProfile.linux": "/bin/bash"
  },
}
```
- VSCode の設定同期
Web で VSCode を使う場合には環境設定を同期しておくと便利です。
https://docs.github.com/en/codespaces/customizing-your-codespace/personalizing-github-codespaces-for-your-account#settings-sync
- Dotfiles
自分の dotfiles を簡単に導入できます。詳しくは下記の導入手順を読んでください。
https://docs.github.com/en/codespaces/customizing-your-codespace/personalizing-github-codespaces-for-your-account#dotfiles

## まとめ

本記事では GitHub Codespaces で Haskell 用の開発環境を構築する手順を紹介しました。
オンラインで簡単に開発環境を構築できるいい時代になりましたね