Skip to content

Commit 6981198

Browse files
committed
Add files
1 parent da17e9c commit 6981198

File tree

14 files changed

+267
-0
lines changed

14 files changed

+267
-0
lines changed

.github/workflows/ci.yml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
if: ${{ github.repository == 'codewars/haskell' }}
12+
steps:
13+
- uses: actions/checkout@v2
14+
- uses: docker/setup-buildx-action@v2
15+
16+
- name: Build image
17+
uses: docker/build-push-action@v3
18+
with:
19+
context: .
20+
push: false
21+
# Make the image available in next step
22+
load: true
23+
tags: ghcr.io/codewars/haskell:latest
24+
cache-from: type=gha
25+
cache-to: type=gha,mode=max
26+
27+
- name: Run Passing Example
28+
run: bin/run passing
29+
30+
- name: Report Image Size
31+
run: |
32+
echo "## Image Size" >> $GITHUB_STEP_SUMMARY
33+
docker image inspect --format '{{.Size}}' ghcr.io/codewars/haskell:latest | numfmt --to=si --suffix=B >> $GITHUB_STEP_SUMMARY

.github/workflows/push-image.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Build and push a Docker image to GitHub Container Registry when
2+
# a new tag is pushed.
3+
name: Push Image
4+
5+
on:
6+
push:
7+
tags:
8+
- "*"
9+
10+
jobs:
11+
build-and-push-image:
12+
if: ${{ github.repository == 'codewars/haskell' }}
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
steps:
18+
- uses: actions/checkout@v2
19+
20+
- name: Set up Docker Buildx
21+
uses: docker/setup-buildx-action@v2
22+
23+
- name: Login to GitHub Container Registry
24+
uses: docker/login-action@v2
25+
with:
26+
registry: ghcr.io
27+
username: codewars
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Build and push image
31+
uses: docker/build-push-action@v3
32+
with:
33+
context: .
34+
push: true
35+
tags: |
36+
ghcr.io/codewars/haskell:latest
37+
ghcr.io/codewars/haskell:${{ github.ref_name }}
38+
cache-from: type=gha
39+
cache-to: type=gha,mode=max

Dockerfile

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
FROM debian:10
2+
# Based on https://github.com/haskell/docker-haskell/blob/fb5c774c38a7ab2e7d233d95368be0f899353496/8.8/buster/Dockerfile
3+
# LTS Haskell 16.25 (2020-12-06) GHC 8.8.4
4+
# See https://www.stackage.org/lts-16.25 for package versions
5+
6+
ENV LANG=C.UTF-8
7+
8+
RUN set -ex; \
9+
apt-get update; \
10+
apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr; \
11+
rm -rf /var/lib/apt/lists/*;
12+
13+
ENV GHC=8.8.4 CABAL_INSTALL=3.2 DEBIAN_KEY=427CB69AAC9D00F2A43CAF1CBA3CBA3FFE22B574 LTS_HASKELL=16.25
14+
RUN set -ex; \
15+
export GNUPGHOME="$(mktemp -d)"; \
16+
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys ${DEBIAN_KEY}; \
17+
gpg --batch --armor --export ${DEBIAN_KEY} > /etc/apt/trusted.gpg.d/haskell.org.gpg.asc; \
18+
gpgconf --kill all; \
19+
echo 'deb http://downloads.haskell.org/debian buster main' > /etc/apt/sources.list.d/ghc.list; \
20+
apt-get update; \
21+
apt-get install -y --no-install-recommends \
22+
cabal-install-${CABAL_INSTALL} \
23+
curl \
24+
g++ \
25+
ghc-${GHC} \
26+
git \
27+
libsqlite3-dev \
28+
libtinfo-dev \
29+
make \
30+
netbase \
31+
openssh-client \
32+
xz-utils \
33+
zlib1g-dev \
34+
# regex-pcre requires pcre
35+
libpcre3 \
36+
libpcre3-dev \
37+
; \
38+
rm -rf "$GNUPGHOME" /var/lib/apt/lists/* /tmp/* /var/tmp/*;
39+
40+
ENV STACK=2.5.1 STACK_RELEASE_KEY=C5705533DA4F78D8664B5DC0575159689BEFB442
41+
RUN set -ex; \
42+
export GNUPGHOME="$(mktemp -d)"; \
43+
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys ${STACK_RELEASE_KEY}; \
44+
curl -fSL https://github.com/commercialhaskell/stack/releases/download/v${STACK}/stack-${STACK}-linux-x86_64.tar.gz -o stack.tar.gz; \
45+
curl -fSL https://github.com/commercialhaskell/stack/releases/download/v${STACK}/stack-${STACK}-linux-x86_64.tar.gz.asc -o stack.tar.gz.asc; \
46+
gpg --batch --verify stack.tar.gz.asc stack.tar.gz; \
47+
gpgconf --kill all; \
48+
tar -xf stack.tar.gz -C /usr/local/bin --strip-components=1; \
49+
stack config set system-ghc --global true; \
50+
stack config set install-ghc --global false; \
51+
rm -rf "$GNUPGHOME" /var/lib/apt/lists/* /stack.tar.gz.asc /stack.tar.gz;
52+
53+
ENV PATH=/opt/cabal/${CABAL_INSTALL}/bin:/opt/ghc/${GHC}/bin:$PATH
54+
55+
56+
RUN set -ex; \
57+
useradd --create-home codewarrior; \
58+
mkdir -p /workspace; \
59+
chown codewarrior: /workspace;
60+
61+
USER codewarrior
62+
ENV USER=codewarrior HOME=/home/codewarrior
63+
ENV PATH=/home/codewarrior/.cabal/bin:/home/codewarrior/.local/bin:$PATH
64+
65+
COPY --chown=codewarrior:codewarrior workspace/ /workspace/
66+
WORKDIR /workspace
67+
RUN stack build
68+
# Sanity check
69+
RUN set -ex; \
70+
stack ghc -- -O -isrc:test --make -o tests -outputdir /tmp test/Main.hs && ./tests; \
71+
rm src/Example.hs test/ExampleSpec.hs tests /tmp/*;

README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# haskell
2+
3+
Container image for Haskell
4+
5+
## Usage
6+
7+
```bash
8+
W=/workspace
9+
# Create container
10+
COMPILE="stack ghc -- -O -j2 +RTS -A128m -n2m -RTS --make -v0 -outputdir /tmp -isrc:test test/Main.hs -o tests"
11+
C=$(docker container create --rm -w $W $IMAGE sh -c "$COMPILE && exec ./tests")
12+
13+
# Copy files from the examples directory
14+
docker container cp ./examples/passing/. $C:$W
15+
16+
# Start
17+
docker container start --attach $C
18+
```
19+
20+
## Building
21+
22+
```bash
23+
docker build -t ghcr.io/codewars/haskell:latest .
24+
```

bin/run

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
set -eu
3+
4+
if [ -z "${IMAGE:+x}" ]; then
5+
IMAGE=ghcr.io/codewars/haskell:latest
6+
fi
7+
8+
W=/workspace
9+
10+
# Create container
11+
COMPILE="stack ghc -- -O -j2 +RTS -A128m -n2m -RTS --make -v0 -outputdir /tmp -isrc:test test/Main.hs -o tests"
12+
C=$(docker container create --rm -w $W $IMAGE sh -c "$COMPILE && exec ./tests")
13+
14+
# Copy files from the examples directory
15+
docker container cp examples/${1:-passing}/. $C:$W
16+
17+
# Run tests
18+
docker container start --attach $C

examples/passing/src/Example.hs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Example where
2+
add :: Num a => a -> a -> a
3+
add = (+)

examples/passing/test/ExampleSpec.hs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module ExampleSpec where
2+
import Test.Hspec
3+
import Example
4+
5+
spec :: Spec
6+
spec = do
7+
describe "add" $ do
8+
it "adds Nums" $ do
9+
(add 1 1) `shouldBe` (2 :: Integer)

workspace/Setup.hs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

workspace/package.yaml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: challenge
2+
version: 0.1.0
3+
license: BSD3
4+
synopsis: Haskell challenge
5+
6+
dependencies:
7+
- base >= 4.7 && < 5
8+
- attoparsec
9+
- haskell-src-exts
10+
- hspec
11+
- hspec-attoparsec
12+
- hspec-codewars
13+
- hspec-contrib
14+
- hspec-formatters-codewars
15+
- hspec-megaparsec
16+
- HUnit-approx
17+
- lens
18+
- megaparsec
19+
- mtl
20+
- parsec
21+
- persistent
22+
- persistent-sqlite
23+
- persistent-template
24+
- random
25+
- regex-pcre
26+
- regex-posix
27+
- regex-tdfa
28+
- split
29+
- text
30+
- transformers
31+
- vector
32+
33+
library:
34+
source-dirs: src

workspace/src/Example.hs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Example where
2+
add :: Num a => a -> a -> a
3+
add = (+)

workspace/stack.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
resolver: lts-16.25
2+
3+
extra-deps:
4+
- url: https://github.com/codewars/hspec-formatters-codewars/archive/v0.1.0.tar.gz
5+
- url: https://github.com/codewars/hspec-codewars/archive/v0.1.0.tar.gz
6+
7+
# Control whether we use the GHC we find on the path
8+
system-ghc: true

workspace/test/ExampleSpec.hs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module ExampleSpec where
2+
import Test.Hspec
3+
import Example
4+
5+
-- main is optional
6+
main :: IO ()
7+
main = hspec spec
8+
9+
spec :: Spec
10+
spec = do
11+
describe "add" $ do
12+
it "adds Nums" $ do
13+
(add 1 1) `shouldBe` (2 :: Integer)

workspace/test/Main.hs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Main where
2+
3+
import Test.Hspec.Runner
4+
import Test.Hspec.Formatters.Codewars (codewars)
5+
6+
import qualified Spec
7+
8+
main :: IO ()
9+
main = hspecWith defaultConfig {configFormatter = Just codewars} Spec.spec

workspace/test/Spec.hs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-}

0 commit comments

Comments
 (0)